mirror of
				https://github.com/KevinMidboe/zoff.git
				synced 2025-10-29 18:00:23 +00:00 
			
		
		
		
	Started on node.js+socket.io+mongoDB on the backend for more responsivnes
This commit is contained in:
		
							
								
								
									
										15
									
								
								server/node_modules/monk/.npmignore
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										15
									
								
								server/node_modules/monk/.npmignore
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
lib-cov
 | 
			
		||||
*.seed
 | 
			
		||||
*.log
 | 
			
		||||
*.csv
 | 
			
		||||
*.dat
 | 
			
		||||
*.out
 | 
			
		||||
*.pid
 | 
			
		||||
*.gz
 | 
			
		||||
 | 
			
		||||
pids
 | 
			
		||||
logs
 | 
			
		||||
results
 | 
			
		||||
 | 
			
		||||
node_modules
 | 
			
		||||
npm-debug.log
 | 
			
		||||
							
								
								
									
										5
									
								
								server/node_modules/monk/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										5
									
								
								server/node_modules/monk/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
language: node_js
 | 
			
		||||
node_js:
 | 
			
		||||
  - 0.6
 | 
			
		||||
  - 0.8
 | 
			
		||||
services: mongodb
 | 
			
		||||
							
								
								
									
										181
									
								
								server/node_modules/monk/History.md
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										181
									
								
								server/node_modules/monk/History.md
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,181 @@
 | 
			
		||||
 | 
			
		||||
1.0.1 / 2015-03-25
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * upgrade; mongoskin to 1.4.13
 | 
			
		||||
 | 
			
		||||
0.9.2 / 2015-02-28
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
 * mongoskin: bump to 1.4.11
 | 
			
		||||
 * Inserting an array returns an array
 | 
			
		||||
 * Cast oids inside of $nor queries
 | 
			
		||||
 * Cast object ids inside of $or and $and queries
 | 
			
		||||
 * Cast object ids inside of $not queries
 | 
			
		||||
 * Added a missing test for updateById
 | 
			
		||||
 * Added removeById
 | 
			
		||||
 * Use `setImmediate` on node 0.10.x
 | 
			
		||||
 | 
			
		||||
0.9.1 / 2014-11-15
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
 * update mongoskin to 1.4.4
 | 
			
		||||
 | 
			
		||||
0.9.0 / 2014-05-09
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
 * addition of `close()` method
 | 
			
		||||
 * updaet mongoskin 1.4.1
 | 
			
		||||
 * fixed URL parsing of replsets
 | 
			
		||||
 * freezed mpromise version
 | 
			
		||||
 * fixed collection distinct after rebase
 | 
			
		||||
 * reimplemented Monk.Promise with MPromise.
 | 
			
		||||
 | 
			
		||||
0.8.1 / 2014-03-01
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
 * fix for parameter handling in `findAndModify`
 | 
			
		||||
 * check for `uri` parameter or throw
 | 
			
		||||
 | 
			
		||||
0.8.0 / 2014-03-01
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
 * added `distinct` support (fixes #52)
 | 
			
		||||
 * added `Promise#then`
 | 
			
		||||
 | 
			
		||||
0.7.1 / 2013-03-03
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * promise: expose `query`
 | 
			
		||||
 | 
			
		||||
0.7.0 / 2012-10-30
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  *: bumped `mongoskin` and therefore `node-mongodb-native`
 | 
			
		||||
 | 
			
		||||
0.6.0 / 2012-10-29
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * collection: added cursor closing support
 | 
			
		||||
  * promise: introduce #destroy
 | 
			
		||||
  * test: added cursor destroy test
 | 
			
		||||
 | 
			
		||||
0.5.0 / 2012-10-03
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * promise: added opts to constructor
 | 
			
		||||
  * util: fix field negation
 | 
			
		||||
  * test: added test for promise options
 | 
			
		||||
  * collection: pass options to promises
 | 
			
		||||
 | 
			
		||||
0.4.0 / 2012-10-03
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * added travis
 | 
			
		||||
  * manager: added Manager#id and Manager#oid
 | 
			
		||||
  * collection: introduced Collection#oid
 | 
			
		||||
  * manager: added Manager#col
 | 
			
		||||
 | 
			
		||||
0.3.0 / 2012-09-06
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * collection: make `findAndModify` accept an oid as the query
 | 
			
		||||
 | 
			
		||||
0.2.1 / 2012-07-14
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * collection: fixed streaming when options are not supplied
 | 
			
		||||
 | 
			
		||||
0.2.0 / 2012-07-14
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * collection: added `count`
 | 
			
		||||
 | 
			
		||||
0.1.15 / 2012-07-14
 | 
			
		||||
===================
 | 
			
		||||
 | 
			
		||||
  * collection: avoid mongoskin warn when buffering commands
 | 
			
		||||
 | 
			
		||||
0.1.14 / 2012-07-09
 | 
			
		||||
===================
 | 
			
		||||
 | 
			
		||||
  * Use any debug. [visionmedia]
 | 
			
		||||
  * Use any mocha. [visionmedia]
 | 
			
		||||
 | 
			
		||||
0.1.13 / 2012-05-28
 | 
			
		||||
===================
 | 
			
		||||
 | 
			
		||||
  * Fixed string-based field selection.
 | 
			
		||||
 | 
			
		||||
0.1.12 / 2012-05-25
 | 
			
		||||
===================
 | 
			
		||||
 | 
			
		||||
  * Added package.json tags.
 | 
			
		||||
  * Added support for update with ids (fixes #4)
 | 
			
		||||
 | 
			
		||||
0.1.11 / 2012-05-22
 | 
			
		||||
===================
 | 
			
		||||
 | 
			
		||||
  * Added support for new objectids through `Collection#id`
 | 
			
		||||
 | 
			
		||||
0.1.10 / 2012-05-21
 | 
			
		||||
===================
 | 
			
		||||
 | 
			
		||||
  * Enhanced findAndModify default behavior for upserts.
 | 
			
		||||
  * Fixed findAndModify.
 | 
			
		||||
 | 
			
		||||
0.1.9 / 2012-05-16
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * Bumped mongoskin
 | 
			
		||||
 | 
			
		||||
0.1.8 / 2012-05-12
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * Fixed mongoskin version
 | 
			
		||||
  * Improved options docs section.
 | 
			
		||||
 | 
			
		||||
0.1.7 / 2012-05-08
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * Added global and collection-level options.
 | 
			
		||||
  * Enabled safe mode by default.
 | 
			
		||||
  * Improved error handling in tests.
 | 
			
		||||
  * Fixed `update` callback with safe: false.
 | 
			
		||||
 | 
			
		||||
0.1.6 / 2012-05-06
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * Added tests for `findById`.
 | 
			
		||||
 | 
			
		||||
0.1.5 / 2012-05-06
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * Added `Collection` references to `Promise`s.
 | 
			
		||||
  * Fixed `findAndModify`.
 | 
			
		||||
 | 
			
		||||
0.1.4 / 2012-05-06
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * Ensured insert calls back with a single object.
 | 
			
		||||
  * Ensured `insert` resolves promise in next tick.
 | 
			
		||||
 | 
			
		||||
0.1.3 / 2012-05-03
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * Exposed `util`
 | 
			
		||||
 | 
			
		||||
0.1.2 / 2012-05-03
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * Make `Collection` inherit from `EventEmitter`.
 | 
			
		||||
 | 
			
		||||
0.1.1 / 2012-04-27
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * Added `updateById`.
 | 
			
		||||
 | 
			
		||||
0.1.0 / 2012-04-23
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * Initial release.
 | 
			
		||||
							
								
								
									
										27
									
								
								server/node_modules/monk/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										27
									
								
								server/node_modules/monk/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
 | 
			
		||||
TESTS = test/*.test.js
 | 
			
		||||
REPORTER = dot
 | 
			
		||||
 | 
			
		||||
test:
 | 
			
		||||
	@make --no-print-directory test-unit
 | 
			
		||||
	@echo "testing promises-A+ implementation ..."
 | 
			
		||||
	@make --no-print-directory test-promises-A
 | 
			
		||||
 | 
			
		||||
test-unit:
 | 
			
		||||
	@DEBUG=$DEBUG,monk,monk:queries ./node_modules/.bin/mocha \
 | 
			
		||||
		--require test/common.js \
 | 
			
		||||
		--reporter $(REPORTER) \
 | 
			
		||||
		--growl \
 | 
			
		||||
		--bail \
 | 
			
		||||
		--slow 1000 \
 | 
			
		||||
		$(TESTS)
 | 
			
		||||
 | 
			
		||||
test-promises-A:
 | 
			
		||||
	@./node_modules/.bin/mocha \
 | 
			
		||||
		--reporter $(REPORTER) \
 | 
			
		||||
		--growl \
 | 
			
		||||
		--bail \
 | 
			
		||||
		--slow 1000 \
 | 
			
		||||
		test/promises-A.js
 | 
			
		||||
 | 
			
		||||
.PHONY: test test-unit test-promises-A
 | 
			
		||||
							
								
								
									
										250
									
								
								server/node_modules/monk/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										250
									
								
								server/node_modules/monk/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,250 @@
 | 
			
		||||
# monk
 | 
			
		||||
 | 
			
		||||
[](https://secure.travis-ci.org/Automattic/monk)
 | 
			
		||||
 | 
			
		||||
Monk is a tiny layer that provides simple yet substantial usability
 | 
			
		||||
improvements for MongoDB usage within Node.JS.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
var db = require('monk')('localhost/mydb');
 | 
			
		||||
var users = db.get('users');
 | 
			
		||||
 | 
			
		||||
users.index('name last');
 | 
			
		||||
users.insert({ name: 'Tobi', bigdata: {} });
 | 
			
		||||
users.find({ name: 'Loki' }, '-bigdata', function () {
 | 
			
		||||
  // exclude bigdata field
 | 
			
		||||
});
 | 
			
		||||
users.find({}, {sort: {name: 1}}, function () {
 | 
			
		||||
  // sorted by name field
 | 
			
		||||
});
 | 
			
		||||
users.remove({ name: 'Loki' });
 | 
			
		||||
 | 
			
		||||
db.close();
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Features
 | 
			
		||||
 | 
			
		||||
- Command buffering. You can start querying right away.
 | 
			
		||||
- Promises built-in for all queries. Easy interoperability with modules.
 | 
			
		||||
- Easy connections / configuration
 | 
			
		||||
- Well-designed signatures
 | 
			
		||||
- Improvements to the MongoDB APIs (eg: `findAndModify` supports the
 | 
			
		||||
  `update` signature style)
 | 
			
		||||
- Auto-casting of `_id` in queries
 | 
			
		||||
- Builds on top of [mongoskin](http://github.com/kissjs/node-mongoskin)
 | 
			
		||||
- Allows to set global options or collection-level options for queries. (eg:
 | 
			
		||||
  `safe` is `true` by default for all queries)
 | 
			
		||||
 | 
			
		||||
## How to use
 | 
			
		||||
 | 
			
		||||
### Connecting
 | 
			
		||||
 | 
			
		||||
#### Single server
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
var db = require('monk')('localhost/mydb')
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Replica set
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
var db = require('monk')('localhost/mydb,192.168.1.1')
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Disconnecting
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
db.close()
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Collections
 | 
			
		||||
 | 
			
		||||
#### Getting one
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
var users = db.get('users')
 | 
			
		||||
// users.insert(), users.update() … (see below)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Dropping
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
users.drop(fn);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Signatures
 | 
			
		||||
 | 
			
		||||
- All commands accept the simple `data[, …], fn`. For example
 | 
			
		||||
    - `find({}, fn)`
 | 
			
		||||
    - `findOne({}, fn)`
 | 
			
		||||
    - `update({}, {}, fn)` `findAndModify({}, {}, fn)`
 | 
			
		||||
    - `findById('id', fn)`
 | 
			
		||||
    - `remove({}, fn)`
 | 
			
		||||
- You can pass options in the middle: `data[, …], options, fn`
 | 
			
		||||
- You can pass fields to select as an array: `data[, …], ['field', …], fn`
 | 
			
		||||
- You can pass fields as a string delimited by spaces:
 | 
			
		||||
  `data[, …], 'field1 field2', fn`
 | 
			
		||||
- To exclude a field, prefix the field name with '-':
 | 
			
		||||
  `data[, …], '-field1', fn`
 | 
			
		||||
 | 
			
		||||
### Promises
 | 
			
		||||
 | 
			
		||||
All methods that perform an async action return a promise.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
var promise = users.insert({});
 | 
			
		||||
promise.type; // 'insert' in this case
 | 
			
		||||
promise.error(function(err){});
 | 
			
		||||
promise.on('error', function(err){});
 | 
			
		||||
promise.on('success', function(doc){});
 | 
			
		||||
promise.on('complete', function(err, doc){});
 | 
			
		||||
promise.success(function(doc){});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Indexes
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
users.index('name.first', fn);
 | 
			
		||||
users.index('email', { unique: true }); // unique
 | 
			
		||||
users.index('name.first name.last') // compound
 | 
			
		||||
users.index({ 'email': 1, 'password': -1 }); // compound with sort
 | 
			
		||||
users.index('email', { sparse: true }, fn); // with options
 | 
			
		||||
users.indexes(fn); // get indexes
 | 
			
		||||
users.dropIndex(name, fn); // drop an index
 | 
			
		||||
users.dropIndexes(fn); // drop all indexes
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Inserting
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
users.insert({ a: 'b' }, function (err, doc) {
 | 
			
		||||
  if (err) throw err;
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Casting
 | 
			
		||||
 | 
			
		||||
To cast to `ObjectId`:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
users.id() // returns new generated ObjectID
 | 
			
		||||
users.id('hexstring') // returns ObjectId
 | 
			
		||||
users.id(obj) // returns ObjectId
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Updating
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
users.update({}, {}, fn);
 | 
			
		||||
users.updateById('id', {}, fn);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Finding
 | 
			
		||||
 | 
			
		||||
#### Many
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
users.find({}, function (err, docs){});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### By ID
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
users.findById('hex representation', function(err, doc){});
 | 
			
		||||
users.findById(oid, function(err, doc){});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Single doc
 | 
			
		||||
 | 
			
		||||
`findOne` also provides the `findById` functionality.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
users.findOne({ name: 'test' }).on('success', function (doc) {});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### And modify
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
users.findAndModify({ query: {}, update: {} });
 | 
			
		||||
users.findAndModify({ _id: '' }, { $set: {} });
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Streaming
 | 
			
		||||
 | 
			
		||||
Note: `stream: true` is optional if you register an `each` handler in the
 | 
			
		||||
same tick. In the following example I just include it for extra clarity.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
users.find({}, { stream: true })
 | 
			
		||||
  .each(function(doc){})
 | 
			
		||||
  .error(function(err){})
 | 
			
		||||
  .success(function(){});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
##### Destroying a cursor
 | 
			
		||||
 | 
			
		||||
On the returned promise you can call `destroy()`. Upon the cursor
 | 
			
		||||
closing the `success` event will be emitted.
 | 
			
		||||
 | 
			
		||||
### Removing
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
users.remove({ a: 'b' }, function (err) {
 | 
			
		||||
  if (err) throw err;
 | 
			
		||||
});
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Global options
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
var db = require('monk')('localhost/mydb')
 | 
			
		||||
db.options.multi = true; // global multi-doc update
 | 
			
		||||
db.get('users').options.multi = false; // collection-level
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Monk sets `safe` to `true` by default.
 | 
			
		||||
 | 
			
		||||
### Query debugging
 | 
			
		||||
 | 
			
		||||
If you wish to see what queries `monk` passes to the driver, simply leverage
 | 
			
		||||
[debug](http://github.com/visionmedia/debug):
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
DEBUG="monk:queries"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
To see all debugging output:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
DEBUG="monk:*"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Contributors
 | 
			
		||||
 | 
			
		||||
- [Guillermo Rauch](http://github.com/rauchg)
 | 
			
		||||
- [Travis Jeffery](http://github.com/travisjeffery)
 | 
			
		||||
 | 
			
		||||
## License
 | 
			
		||||
 | 
			
		||||
(The MIT License)
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2012 Guillermo Rauch <guillermo@learnboost.com>
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining
 | 
			
		||||
a copy of this software and associated documentation files (the
 | 
			
		||||
'Software'), to deal in the Software without restriction, including
 | 
			
		||||
without limitation the rights to use, copy, modify, merge, publish,
 | 
			
		||||
distribute, sublicense, and/or sell copies of the Software, and to
 | 
			
		||||
permit persons to whom the Software is furnished to do so, subject to
 | 
			
		||||
the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be
 | 
			
		||||
included in all copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
 | 
			
		||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
			
		||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | 
			
		||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
			
		||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 | 
			
		||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 | 
			
		||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
							
								
								
									
										604
									
								
								server/node_modules/monk/lib/collection.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										604
									
								
								server/node_modules/monk/lib/collection.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,604 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Module dependencies.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
var util = require('./util')
 | 
			
		||||
  , debug = require('debug')('monk:queries')
 | 
			
		||||
  , EventEmitter = require('events').EventEmitter
 | 
			
		||||
  , Promise = require('./promise')
 | 
			
		||||
  , immediately = global.setImmediate || process.nextTick;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Module exports
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
module.exports = Collection;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Collection.
 | 
			
		||||
 *
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function Collection (manager, name) {
 | 
			
		||||
  this.manager = manager;
 | 
			
		||||
  this.driver = manager.driver;
 | 
			
		||||
  this.helper = manager.helper;
 | 
			
		||||
  this.name = name;
 | 
			
		||||
  this.col = this.driver.collection(name);
 | 
			
		||||
  this.col.id = this.helper.id;
 | 
			
		||||
  this.options = {};
 | 
			
		||||
  this.col.emitter = this.col.emitter || this.col._emitter;
 | 
			
		||||
  this.col.emitter.setMaxListeners(Infinity);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Inherits from EventEmitter.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Collection.prototype.__proto__ = EventEmitter.prototype;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Casts to objectid
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Mixed} hex id or ObjectId
 | 
			
		||||
 * @return {ObjectId}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Collection.prototype.id =
 | 
			
		||||
Collection.prototype.oid = function (str) {
 | 
			
		||||
  if (null == str) return this.col.id();
 | 
			
		||||
  return 'string' == typeof str ? this.col.id(str) : str;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Opts utility.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Collection.prototype.opts = function (opts) {
 | 
			
		||||
  opts = util.options(opts || {});
 | 
			
		||||
 | 
			
		||||
  for (var i in this.manager.options) {
 | 
			
		||||
    if (!(i in opts) && !(i in this.options)) {
 | 
			
		||||
      opts[i] = this.manager.options[i];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (var i in this.options) {
 | 
			
		||||
    if (!(i in opts)) {
 | 
			
		||||
      opts[i] = this.options[i];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return opts;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set up indexes.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Object|String|Array} fields
 | 
			
		||||
 * @param {Object|Function} optional, options or callback
 | 
			
		||||
 * @param {Function} optional, callback
 | 
			
		||||
 * @return {Promise}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Collection.prototype.index =
 | 
			
		||||
Collection.prototype.ensureIndex = function (fields, opts, fn) {
 | 
			
		||||
  if ('function' == typeof opts) {
 | 
			
		||||
    fn = opts;
 | 
			
		||||
    opts = {};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var fields = util.fields(fields)
 | 
			
		||||
    , opts = opts || {}
 | 
			
		||||
    , promise = new Promise(this, 'index');
 | 
			
		||||
 | 
			
		||||
  if (fn) {
 | 
			
		||||
    promise.complete(fn);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // query
 | 
			
		||||
  debug('%s ensureIndex %j (%j)', this.name, fields, opts);
 | 
			
		||||
  this.col.ensureIndex(fields, opts, promise.resolve);
 | 
			
		||||
 | 
			
		||||
  return promise;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Gets all indexes.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Function} callback
 | 
			
		||||
 * @return {Promise}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Collection.prototype.indexes = function (fn) {
 | 
			
		||||
  var promise = new Promise(this, 'indexes');
 | 
			
		||||
 | 
			
		||||
  if (fn) {
 | 
			
		||||
    promise.complete(fn);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // query
 | 
			
		||||
  debug('%s indexInformation', this.name);
 | 
			
		||||
  this.col.indexInformation(promise.resolve);
 | 
			
		||||
 | 
			
		||||
  return promise;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * update
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Object} search query
 | 
			
		||||
 * @param {Object} update obj
 | 
			
		||||
 * @param {Object|String|Array} optional, options or fields
 | 
			
		||||
 * @param {Function} callback
 | 
			
		||||
 * @return {Promise}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Collection.prototype.update = function (search, update, opts, fn) {
 | 
			
		||||
  if ('string' == typeof search || 'function' == typeof search.toHexString) {
 | 
			
		||||
    return this.update({ _id: search }, update, opts, fn);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if ('function' == typeof opts) {
 | 
			
		||||
    fn = opts;
 | 
			
		||||
    opts = {};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  opts = this.opts(opts);
 | 
			
		||||
  var promise = new Promise(this, 'update', opts);
 | 
			
		||||
 | 
			
		||||
  if (fn) {
 | 
			
		||||
    promise.complete(fn);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // cast
 | 
			
		||||
  search = this.cast(search);
 | 
			
		||||
  update = this.cast(update);
 | 
			
		||||
 | 
			
		||||
  // query
 | 
			
		||||
  var callback = opts.safe ? promise.resolve : function () {
 | 
			
		||||
    // node-mongodb-native will send err=undefined and call the fn
 | 
			
		||||
    // in the same tick if safe: false
 | 
			
		||||
    var args = arguments;
 | 
			
		||||
    args[0] = args[0] || null;
 | 
			
		||||
    immediately(function () {
 | 
			
		||||
      promise.resolve.apply(promise, args);
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  debug('%s update %j with %j', this.name, search, update);
 | 
			
		||||
  promise.query = { query: search, update: update };
 | 
			
		||||
  this.col.update(search, update, opts, callback);
 | 
			
		||||
 | 
			
		||||
  return promise;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * update by id helper
 | 
			
		||||
 *
 | 
			
		||||
 * @param {String|Object} object id
 | 
			
		||||
 * @param {Object} update obj
 | 
			
		||||
 * @param {Object|String|Array} optional, options or fields
 | 
			
		||||
 * @param {Function} callback
 | 
			
		||||
 * @return {Promise}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Collection.prototype.updateById = function (id, obj, opts, fn) {
 | 
			
		||||
  return this.update({ _id: id }, obj, opts, fn);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * remove
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Object} search query
 | 
			
		||||
 * @param {Object|Function} optional, options or callback
 | 
			
		||||
 * @param {Function} optional, callback
 | 
			
		||||
 * @return {Promise}
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Collection.prototype.remove = function (search, opts, fn) {
 | 
			
		||||
  if ('function' == typeof opts) {
 | 
			
		||||
    fn = opts;
 | 
			
		||||
    opts = {};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  opts = this.opts(opts);
 | 
			
		||||
  var promise = new Promise(this, 'remove', opts);
 | 
			
		||||
 | 
			
		||||
  if (fn) {
 | 
			
		||||
    promise.complete(fn);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // cast
 | 
			
		||||
  search = this.cast(search);
 | 
			
		||||
 | 
			
		||||
  // query
 | 
			
		||||
  debug('%s remove %j with %j', this.name, search, opts);
 | 
			
		||||
  promise.query = search;
 | 
			
		||||
  this.col.remove(search, opts, promise.resolve);
 | 
			
		||||
 | 
			
		||||
  return promise;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * remove by ID
 | 
			
		||||
 *
 | 
			
		||||
 * @param {String} hex id
 | 
			
		||||
 * @param {Object|String|Array} optional, options or fields
 | 
			
		||||
 * @param {Function} completion callback
 | 
			
		||||
 * @return {Promise}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Collection.prototype.removeById = function (id, opts, fn) {
 | 
			
		||||
  return this.remove({ _id: id }, opts, fn);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * findAndModify
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Object} search query, or { query, update } object
 | 
			
		||||
 * @param {Object} optional, update object
 | 
			
		||||
 * @param {Object|String|Array} optional, options or fields
 | 
			
		||||
 * @param {Function} callback
 | 
			
		||||
 * @return {Promise}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Collection.prototype.findAndModify = function (query, update, opts, fn) {
 | 
			
		||||
  query = query || {};
 | 
			
		||||
 | 
			
		||||
  if ('object' != typeof query.query && 'object' != typeof query.update) {
 | 
			
		||||
    query = {
 | 
			
		||||
        query: query
 | 
			
		||||
      , update: update
 | 
			
		||||
    };
 | 
			
		||||
  } else {
 | 
			
		||||
    fn = opts;
 | 
			
		||||
    opts = update;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if ('string' == typeof query.query || 'function' == typeof query.query.toHexString) {
 | 
			
		||||
    query.query = { _id: query.query };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if ('function' == typeof opts) {
 | 
			
		||||
    fn = opts;
 | 
			
		||||
    opts = {};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  opts = opts || {};
 | 
			
		||||
 | 
			
		||||
  // `new` defaults to `true` for upserts
 | 
			
		||||
  if (null == opts.new && opts.upsert) {
 | 
			
		||||
    opts.new = true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var promise = new Promise(this, 'findAndModify', opts);
 | 
			
		||||
 | 
			
		||||
  if (fn) {
 | 
			
		||||
    promise.complete(fn);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // cast
 | 
			
		||||
  query.query = this.cast(query.query);
 | 
			
		||||
  query.update = this.cast(query.update);
 | 
			
		||||
 | 
			
		||||
  // query
 | 
			
		||||
  debug('%s findAndModify %j with %j', this.name, query.query, query.update);
 | 
			
		||||
  promise.query = query;
 | 
			
		||||
  this.col.findAndModify(
 | 
			
		||||
      query.query
 | 
			
		||||
    , []
 | 
			
		||||
    , query.update
 | 
			
		||||
    , this.opts(opts)
 | 
			
		||||
    , promise.resolve
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  return promise;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * insert
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Object} data
 | 
			
		||||
 * @param {Object|String|Array} optional, options or fields
 | 
			
		||||
 * @param {Function} callback
 | 
			
		||||
 * @return {Promise}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Collection.prototype.insert = function (data, opts, fn) {
 | 
			
		||||
  if ('function' == typeof opts) {
 | 
			
		||||
    fn = opts;
 | 
			
		||||
    opts = {};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  opts = this.opts(opts);
 | 
			
		||||
  var promise = new Promise(this, 'insert', opts);
 | 
			
		||||
 | 
			
		||||
  if (fn) {
 | 
			
		||||
    promise.complete(fn);
 | 
			
		||||
  }
 | 
			
		||||
  var arrayInsert = Array.isArray(data);
 | 
			
		||||
 | 
			
		||||
  // cast
 | 
			
		||||
  data = this.cast(data);
 | 
			
		||||
 | 
			
		||||
  // query
 | 
			
		||||
  debug('%s insert %j', this.name, data);
 | 
			
		||||
  promise.query = data;
 | 
			
		||||
  this.col.insert(data, opts, function (err, docs) {
 | 
			
		||||
    immediately(function () {
 | 
			
		||||
      var res = docs;
 | 
			
		||||
      if (docs && !arrayInsert) {
 | 
			
		||||
        res = docs[0];
 | 
			
		||||
      }
 | 
			
		||||
      promise.resolve.call(promise, err, res);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  return promise;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * findOne by ID
 | 
			
		||||
 *
 | 
			
		||||
 * @param {String} hex id
 | 
			
		||||
 * @param {Object|String|Array} optional, options or fields
 | 
			
		||||
 * @param {Function} completion callback
 | 
			
		||||
 * @return {Promise}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Collection.prototype.findById = function (id, opts, fn) {
 | 
			
		||||
  return this.findOne({ _id: id }, opts, fn);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * find
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Object} query
 | 
			
		||||
 * @param {Object|String|Array} optional, options or fields
 | 
			
		||||
 * @param {Function} completion callback
 | 
			
		||||
 * @return {Promise}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Collection.prototype.find = function (query, opts, fn) {
 | 
			
		||||
  if ('function' == typeof opts) {
 | 
			
		||||
    fn = opts;
 | 
			
		||||
    opts = {};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // cast
 | 
			
		||||
  query = this.cast(query);
 | 
			
		||||
 | 
			
		||||
  // opts
 | 
			
		||||
  opts = this.opts(opts);
 | 
			
		||||
 | 
			
		||||
  // query
 | 
			
		||||
  debug('%s find %j', this.name, query);
 | 
			
		||||
  var cursor = this.col.find(query, opts);
 | 
			
		||||
 | 
			
		||||
  // promise
 | 
			
		||||
  var promise = new Promise(this, 'find', opts);
 | 
			
		||||
  promise.query = query;
 | 
			
		||||
 | 
			
		||||
  if (fn) {
 | 
			
		||||
    promise.complete(fn);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (null == opts.stream) {
 | 
			
		||||
    immediately(function () {
 | 
			
		||||
      if (promise.listeners('each').length) {
 | 
			
		||||
        stream();
 | 
			
		||||
      } else {
 | 
			
		||||
        cursor.toArray(promise.resolve);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  } else if (opts.stream) {
 | 
			
		||||
    stream();
 | 
			
		||||
  } else {
 | 
			
		||||
    cursor.toArray(promise.resolve);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function stream () {
 | 
			
		||||
    var didClose = false;
 | 
			
		||||
 | 
			
		||||
    cursor.each(function (err, doc) {
 | 
			
		||||
      if (didClose && !err) {
 | 
			
		||||
        // emit success
 | 
			
		||||
        err = doc = null;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (err) {
 | 
			
		||||
        promise.reject(err);
 | 
			
		||||
      } else if (doc) {
 | 
			
		||||
        promise.emit('each', doc);
 | 
			
		||||
      } else {
 | 
			
		||||
        promise.fulfill();
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    promise.once('destroy', function(){
 | 
			
		||||
      didClose = true;
 | 
			
		||||
      cursor = cursor.cursor || cursor;
 | 
			
		||||
      cursor.close();
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return promise;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * distinct
 | 
			
		||||
 *
 | 
			
		||||
 * @param {String} distinct field to select
 | 
			
		||||
 * @param {Object} optional, query
 | 
			
		||||
 * @param {Function} completion callback
 | 
			
		||||
 * @return {Promise}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Collection.prototype.distinct = function (field, query, fn) {
 | 
			
		||||
  if ('function' == typeof query) {
 | 
			
		||||
    fn = query;
 | 
			
		||||
    query = {};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var promise = new Promise(this, 'distinct');
 | 
			
		||||
 | 
			
		||||
  if (fn) {
 | 
			
		||||
    promise.complete(fn);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // cast
 | 
			
		||||
  query = this.cast(query);
 | 
			
		||||
 | 
			
		||||
  // query
 | 
			
		||||
  debug('%s distinct %s (%j)', this.name, field, query);
 | 
			
		||||
  promise.query = query;
 | 
			
		||||
  this.col.distinct(field, query, promise.resolve);
 | 
			
		||||
 | 
			
		||||
  return promise;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * count
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Object} query
 | 
			
		||||
 * @param {Function} completion callback
 | 
			
		||||
 * @return {Promise}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Collection.prototype.count = function (query, fn) {
 | 
			
		||||
  var promise = new Promise(this, 'find');
 | 
			
		||||
 | 
			
		||||
  if (fn) {
 | 
			
		||||
    promise.complete(fn);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // cast
 | 
			
		||||
  query = this.cast(query);
 | 
			
		||||
 | 
			
		||||
  // query
 | 
			
		||||
  debug('%s count %j', this.name, query);
 | 
			
		||||
  promise.query = query;
 | 
			
		||||
  this.col.count(query, promise.resolve);
 | 
			
		||||
 | 
			
		||||
  return promise;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * findOne
 | 
			
		||||
 *
 | 
			
		||||
 * @param {String|ObjectId|Object} query
 | 
			
		||||
 * @param {Object} options
 | 
			
		||||
 * @param {Function} completion callback
 | 
			
		||||
 * @return {Promise}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Collection.prototype.findOne = function (search, opts, fn) {
 | 
			
		||||
  search = search || {};
 | 
			
		||||
 | 
			
		||||
  if ('string' == typeof search || 'function' == typeof search.toHexString) {
 | 
			
		||||
    return this.findById(search, opts, fn);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if ('function' == typeof opts) {
 | 
			
		||||
    fn = opts;
 | 
			
		||||
    opts = {};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  opts = this.opts(opts);
 | 
			
		||||
  var promise = new Promise(this, 'findOne', opts);
 | 
			
		||||
 | 
			
		||||
  if (fn) {
 | 
			
		||||
    promise.complete(fn);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // cast
 | 
			
		||||
  search = this.cast(search);
 | 
			
		||||
 | 
			
		||||
  // query
 | 
			
		||||
  debug('%s findOne %j', this.name, search);
 | 
			
		||||
  promise.query = search;
 | 
			
		||||
  this.col.findOne(search, opts, promise.resolve);
 | 
			
		||||
 | 
			
		||||
  return promise;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Applies ObjectId casting to _id fields.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Object} optional, query
 | 
			
		||||
 * @return {Object} query
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Collection.prototype.cast = function (obj) {
 | 
			
		||||
  obj = obj || {};
 | 
			
		||||
 | 
			
		||||
  if (obj._id) {
 | 
			
		||||
    obj._id = this.id(obj._id);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (obj.$set && obj.$set._id) {
 | 
			
		||||
    obj.$set._id = this.id(obj.$set._id);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (obj.$not && obj.$not._id) {
 | 
			
		||||
    obj.$not._id = this.id(obj.$not._id);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (obj.$and && Array.isArray(obj.$and)) {
 | 
			
		||||
    obj.$and = obj.$and.map(function (q) {
 | 
			
		||||
      return this.cast(q);
 | 
			
		||||
    }, this);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (obj.$or && Array.isArray(obj.$or)) {
 | 
			
		||||
    obj.$or = obj.$or.map(function (q) {
 | 
			
		||||
      return this.cast(q);
 | 
			
		||||
    }, this);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (obj.$nor && Array.isArray(obj.$nor)) {
 | 
			
		||||
    obj.$nor = obj.$nor.map(function (q) {
 | 
			
		||||
      return this.cast(q);
 | 
			
		||||
    }, this);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return obj;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Drops the collection.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Function} optional, callback
 | 
			
		||||
 * @return {Promise}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Collection.prototype.drop = function (fn) {
 | 
			
		||||
  var promise = new Promise(this, 'drop');
 | 
			
		||||
 | 
			
		||||
  if (fn) {
 | 
			
		||||
    promise.complete(fn);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  debug('%s drop', this.name);
 | 
			
		||||
  promise.query = this.name;
 | 
			
		||||
  this.col.drop(promise.resolve);
 | 
			
		||||
 | 
			
		||||
  return promise;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										130
									
								
								server/node_modules/monk/lib/manager.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										130
									
								
								server/node_modules/monk/lib/manager.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,130 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Module dependencies.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
var mongoskin = require('mongoskin')
 | 
			
		||||
  , debug = require('debug')('monk:manager')
 | 
			
		||||
  , Collection = require('./collection')
 | 
			
		||||
  , ObjectId = mongoskin.ObjectID
 | 
			
		||||
  , EventEmitter = require('events').EventEmitter
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Module exports.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
module.exports = Manager;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Manager constructor.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Array|String} connection uri. replica sets can be an array or
 | 
			
		||||
 * comma-separated
 | 
			
		||||
 * @param {Object|Function} options or connect callback
 | 
			
		||||
 * @param {Function} connect callback
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function Manager (uri, opts, fn) {
 | 
			
		||||
  if (!uri) {
 | 
			
		||||
    throw Error('No connection URI provided.');
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  if (!(this instanceof Manager)) {
 | 
			
		||||
    return new Manager(uri, opts, fn);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if ('function' == typeof opts) {
 | 
			
		||||
    fn = opts;
 | 
			
		||||
    opts = {};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  opts = opts || {};
 | 
			
		||||
  opts.safe = true;
 | 
			
		||||
 | 
			
		||||
  if (Array.isArray(uri)) {
 | 
			
		||||
    if (!opts.database) {
 | 
			
		||||
      for (var i = 0, l = uri.length; i < l; i++) {
 | 
			
		||||
        if (!opts.database) {
 | 
			
		||||
          opts.database = uri[i].replace(/([^\/])+\/?/, '');
 | 
			
		||||
        }
 | 
			
		||||
        uri[i] = uri[i].replace(/\/.*/, '');
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    uri = uri.join(",") + "/" + opts.database;
 | 
			
		||||
    debug('repl set connection "%j" to database "%s"', uri, opts.database);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if ('string' == typeof uri) {
 | 
			
		||||
    if ( ! /^mongodb\:\/\//.test(uri)) {
 | 
			
		||||
      uri = 'mongodb://' + uri;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.driver = mongoskin.db(uri, opts);
 | 
			
		||||
  this.helper = mongoskin.helper;
 | 
			
		||||
  this.helper.id = ObjectId;
 | 
			
		||||
  this.driver.open(this.onOpen.bind(this));
 | 
			
		||||
  this.collections = {};
 | 
			
		||||
  this.options = { safe: true };
 | 
			
		||||
 | 
			
		||||
  if (fn) {
 | 
			
		||||
    this.once('open', fn);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Inherits from EventEmitter
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Manager.prototype.__proto__ = EventEmitter.prototype;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Open callback.
 | 
			
		||||
 *
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Manager.prototype.onOpen = function () {
 | 
			
		||||
  this.emit('open');
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Closes the connection.
 | 
			
		||||
 *
 | 
			
		||||
 * @return {Manager} for chaining
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Manager.prototype.close = function (fn) {
 | 
			
		||||
  this.driver.close(fn);
 | 
			
		||||
  return this;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Gets a collection.
 | 
			
		||||
 *
 | 
			
		||||
 * @return {Collection} collection to query against
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Manager.prototype.col =
 | 
			
		||||
Manager.prototype.get = function (name) {
 | 
			
		||||
  if (!this.collections[name]) {
 | 
			
		||||
    this.collections[name] = new Collection(this, name);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return this.collections[name];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Casts to objectid
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Mixed} hex id or ObjectId
 | 
			
		||||
 * @return {ObjectId}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Manager.prototype.id =
 | 
			
		||||
Manager.prototype.oid = function (str) {
 | 
			
		||||
  if (null == str) return ObjectId();
 | 
			
		||||
  return 'string' == typeof str ? ObjectId.createFromHexString(str) : str;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										30
									
								
								server/node_modules/monk/lib/monk.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										30
									
								
								server/node_modules/monk/lib/monk.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Module exports.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
module.exports = exports = require('./manager');
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Expose Collection.
 | 
			
		||||
 *
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
exports.Collection = require('./collection');
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Expose Promise.
 | 
			
		||||
 *
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
exports.Promise = require('./promise');
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Expose util.
 | 
			
		||||
 *
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
exports.util = require('./util');
 | 
			
		||||
							
								
								
									
										83
									
								
								server/node_modules/monk/lib/promise.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										83
									
								
								server/node_modules/monk/lib/promise.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,83 @@
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Module dependencies.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
var MPromise = require('mpromise');
 | 
			
		||||
var immediately = global.setImmediate || process.nextTick;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Module exports.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
module.exports = Promise;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Promise constructor.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Collection} collection
 | 
			
		||||
 * @param {String} type
 | 
			
		||||
 * @param {Object} query options
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function Promise (col, type, opts) {
 | 
			
		||||
  this.col = col;
 | 
			
		||||
  this.type = type;
 | 
			
		||||
  this.opts = opts || {};
 | 
			
		||||
 | 
			
		||||
  // MPromise constructor
 | 
			
		||||
  MPromise.call(this);
 | 
			
		||||
 | 
			
		||||
  // Compability methods
 | 
			
		||||
  this.success = this.onFulfill;
 | 
			
		||||
  this.error = this.onReject;
 | 
			
		||||
  this.complete = this.onResolve;
 | 
			
		||||
  this.onResolve(this.emit.bind(this,'complete'));
 | 
			
		||||
 | 
			
		||||
  // for practical purposes
 | 
			
		||||
  this.resolve = MPromise.prototype.resolve.bind(this);
 | 
			
		||||
  this.fulfill = MPromise.prototype.fulfill.bind(this);
 | 
			
		||||
  this.reject = MPromise.prototype.reject.bind(this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
 * event names
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Promise.SUCCESS = 'success';
 | 
			
		||||
Promise.FAILURE = 'error';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Inherits from MPromise.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Promise.prototype.__proto__ = MPromise.prototype;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Each method
 | 
			
		||||
 *
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Promise.prototype.each = function (fn) {
 | 
			
		||||
  if (fn) {
 | 
			
		||||
    this.on('each', fn);
 | 
			
		||||
  }
 | 
			
		||||
  return this;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Destroys the promise.
 | 
			
		||||
 *
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
Promise.prototype.destroy = function(){
 | 
			
		||||
  this.emit('destroy');
 | 
			
		||||
  var self = this;
 | 
			
		||||
  immediately(function(){
 | 
			
		||||
    // null the query ref
 | 
			
		||||
    delete self.query;
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										44
									
								
								server/node_modules/monk/lib/util.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										44
									
								
								server/node_modules/monk/lib/util.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Parses all the possible ways of expressing fields.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {String|Object|Array} fields
 | 
			
		||||
 * @return {Object} fields in object format
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
exports.fields = function (obj) {
 | 
			
		||||
  if (!Array.isArray(obj) && 'object' == typeof obj) {
 | 
			
		||||
    return obj;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var fields = {};
 | 
			
		||||
  obj = 'string' == typeof obj ? obj.split(' ') : (obj || []);
 | 
			
		||||
 | 
			
		||||
  for (var i = 0, l = obj.length; i < l; i++) {
 | 
			
		||||
    if ('-' == obj[i][0]) {
 | 
			
		||||
      fields[obj[i].substr(1)] = 0;
 | 
			
		||||
    } else {
 | 
			
		||||
      fields[obj[i]] = 1;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return fields;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Parses an object format.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {String|Array|Object} fields or options
 | 
			
		||||
 * @return {Object} options
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
exports.options = function (opts) {
 | 
			
		||||
  if ('string' == typeof opts || Array.isArray(opts)) {
 | 
			
		||||
    return { fields: exports.fields(opts) };
 | 
			
		||||
  }
 | 
			
		||||
  opts = opts || {};
 | 
			
		||||
  opts.fields = exports.fields(opts.fields);
 | 
			
		||||
  return opts;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										3
									
								
								server/node_modules/monk/node_modules/debug/.jshintrc
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										3
									
								
								server/node_modules/monk/node_modules/debug/.jshintrc
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
{
 | 
			
		||||
  "laxbreak": true
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								server/node_modules/monk/node_modules/debug/.npmignore
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										6
									
								
								server/node_modules/monk/node_modules/debug/.npmignore
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
support
 | 
			
		||||
test
 | 
			
		||||
examples
 | 
			
		||||
example
 | 
			
		||||
*.sock
 | 
			
		||||
dist
 | 
			
		||||
							
								
								
									
										186
									
								
								server/node_modules/monk/node_modules/debug/History.md
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										186
									
								
								server/node_modules/monk/node_modules/debug/History.md
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,186 @@
 | 
			
		||||
 | 
			
		||||
2.1.3 / 2015-03-13
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * Updated stdout/stderr example (#186)
 | 
			
		||||
  * Updated example/stdout.js to match debug current behaviour
 | 
			
		||||
  * Renamed example/stderr.js to stdout.js
 | 
			
		||||
  * Update Readme.md (#184)
 | 
			
		||||
  * replace high intensity foreground color for bold (#182, #183)
 | 
			
		||||
 | 
			
		||||
2.1.2 / 2015-03-01
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * dist: recompile
 | 
			
		||||
  * update "ms" to v0.7.0
 | 
			
		||||
  * package: update "browserify" to v9.0.3
 | 
			
		||||
  * component: fix "ms.js" repo location
 | 
			
		||||
  * changed bower package name
 | 
			
		||||
  * updated documentation about using debug in a browser
 | 
			
		||||
  * fix: security error on safari (#167, #168, @yields)
 | 
			
		||||
 | 
			
		||||
2.1.1 / 2014-12-29
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * browser: use `typeof` to check for `console` existence
 | 
			
		||||
  * browser: check for `console.log` truthiness (fix IE 8/9)
 | 
			
		||||
  * browser: add support for Chrome apps
 | 
			
		||||
  * Readme: added Windows usage remarks
 | 
			
		||||
  * Add `bower.json` to properly support bower install
 | 
			
		||||
 | 
			
		||||
2.1.0 / 2014-10-15
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * node: implement `DEBUG_FD` env variable support
 | 
			
		||||
  * package: update "browserify" to v6.1.0
 | 
			
		||||
  * package: add "license" field to package.json (#135, @panuhorsmalahti)
 | 
			
		||||
 | 
			
		||||
2.0.0 / 2014-09-01
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * package: update "browserify" to v5.11.0
 | 
			
		||||
  * node: use stderr rather than stdout for logging (#29, @stephenmathieson)
 | 
			
		||||
 | 
			
		||||
1.0.4 / 2014-07-15
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * dist: recompile
 | 
			
		||||
  * example: remove `console.info()` log usage
 | 
			
		||||
  * example: add "Content-Type" UTF-8 header to browser example
 | 
			
		||||
  * browser: place %c marker after the space character
 | 
			
		||||
  * browser: reset the "content" color via `color: inherit`
 | 
			
		||||
  * browser: add colors support for Firefox >= v31
 | 
			
		||||
  * debug: prefer an instance `log()` function over the global one (#119)
 | 
			
		||||
  * Readme: update documentation about styled console logs for FF v31 (#116, @wryk)
 | 
			
		||||
 | 
			
		||||
1.0.3 / 2014-07-09
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * Add support for multiple wildcards in namespaces (#122, @seegno)
 | 
			
		||||
  * browser: fix lint
 | 
			
		||||
 | 
			
		||||
1.0.2 / 2014-06-10
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * browser: update color palette (#113, @gscottolson)
 | 
			
		||||
  * common: make console logging function configurable (#108, @timoxley)
 | 
			
		||||
  * node: fix %o colors on old node <= 0.8.x
 | 
			
		||||
  * Makefile: find node path using shell/which (#109, @timoxley)
 | 
			
		||||
 | 
			
		||||
1.0.1 / 2014-06-06
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * browser: use `removeItem()` to clear localStorage
 | 
			
		||||
  * browser, node: don't set DEBUG if namespaces is undefined (#107, @leedm777)
 | 
			
		||||
  * package: add "contributors" section
 | 
			
		||||
  * node: fix comment typo
 | 
			
		||||
  * README: list authors
 | 
			
		||||
 | 
			
		||||
1.0.0 / 2014-06-04
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * make ms diff be global, not be scope
 | 
			
		||||
  * debug: ignore empty strings in enable()
 | 
			
		||||
  * node: make DEBUG_COLORS able to disable coloring
 | 
			
		||||
  * *: export the `colors` array
 | 
			
		||||
  * npmignore: don't publish the `dist` dir
 | 
			
		||||
  * Makefile: refactor to use browserify
 | 
			
		||||
  * package: add "browserify" as a dev dependency
 | 
			
		||||
  * Readme: add Web Inspector Colors section
 | 
			
		||||
  * node: reset terminal color for the debug content
 | 
			
		||||
  * node: map "%o" to `util.inspect()`
 | 
			
		||||
  * browser: map "%j" to `JSON.stringify()`
 | 
			
		||||
  * debug: add custom "formatters"
 | 
			
		||||
  * debug: use "ms" module for humanizing the diff
 | 
			
		||||
  * Readme: add "bash" syntax highlighting
 | 
			
		||||
  * browser: add Firebug color support
 | 
			
		||||
  * browser: add colors for WebKit browsers
 | 
			
		||||
  * node: apply log to `console`
 | 
			
		||||
  * rewrite: abstract common logic for Node & browsers
 | 
			
		||||
  * add .jshintrc file
 | 
			
		||||
 | 
			
		||||
0.8.1 / 2014-04-14
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * package: re-add the "component" section
 | 
			
		||||
 | 
			
		||||
0.8.0 / 2014-03-30
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * add `enable()` method for nodejs. Closes #27
 | 
			
		||||
  * change from stderr to stdout
 | 
			
		||||
  * remove unnecessary index.js file
 | 
			
		||||
 | 
			
		||||
0.7.4 / 2013-11-13
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * remove "browserify" key from package.json (fixes something in browserify)
 | 
			
		||||
 | 
			
		||||
0.7.3 / 2013-10-30
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * fix: catch localStorage security error when cookies are blocked (Chrome)
 | 
			
		||||
  * add debug(err) support. Closes #46
 | 
			
		||||
  * add .browser prop to package.json. Closes #42
 | 
			
		||||
 | 
			
		||||
0.7.2 / 2013-02-06
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * fix package.json
 | 
			
		||||
  * fix: Mobile Safari (private mode) is broken with debug
 | 
			
		||||
  * fix: Use unicode to send escape character to shell instead of octal to work with strict mode javascript
 | 
			
		||||
 | 
			
		||||
0.7.1 / 2013-02-05
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * add repository URL to package.json
 | 
			
		||||
  * add DEBUG_COLORED to force colored output
 | 
			
		||||
  * add browserify support
 | 
			
		||||
  * fix component. Closes #24
 | 
			
		||||
 | 
			
		||||
0.7.0 / 2012-05-04
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * Added .component to package.json
 | 
			
		||||
  * Added debug.component.js build
 | 
			
		||||
 | 
			
		||||
0.6.0 / 2012-03-16
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * Added support for "-" prefix in DEBUG [Vinay Pulim]
 | 
			
		||||
  * Added `.enabled` flag to the node version [TooTallNate]
 | 
			
		||||
 | 
			
		||||
0.5.0 / 2012-02-02
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * Added: humanize diffs. Closes #8
 | 
			
		||||
  * Added `debug.disable()` to the CS variant
 | 
			
		||||
  * Removed padding. Closes #10
 | 
			
		||||
  * Fixed: persist client-side variant again. Closes #9
 | 
			
		||||
 | 
			
		||||
0.4.0 / 2012-02-01
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * Added browser variant support for older browsers [TooTallNate]
 | 
			
		||||
  * Added `debug.enable('project:*')` to browser variant [TooTallNate]
 | 
			
		||||
  * Added padding to diff (moved it to the right)
 | 
			
		||||
 | 
			
		||||
0.3.0 / 2012-01-26
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * Added millisecond diff when isatty, otherwise UTC string
 | 
			
		||||
 | 
			
		||||
0.2.0 / 2012-01-22
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * Added wildcard support
 | 
			
		||||
 | 
			
		||||
0.1.0 / 2011-12-02
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * Added: remove colors unless stderr isatty [TooTallNate]
 | 
			
		||||
 | 
			
		||||
0.0.1 / 2010-01-03
 | 
			
		||||
==================
 | 
			
		||||
 | 
			
		||||
  * Initial release
 | 
			
		||||
							
								
								
									
										33
									
								
								server/node_modules/monk/node_modules/debug/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										33
									
								
								server/node_modules/monk/node_modules/debug/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
 | 
			
		||||
# get Makefile directory name: http://stackoverflow.com/a/5982798/376773
 | 
			
		||||
THIS_MAKEFILE_PATH:=$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
 | 
			
		||||
THIS_DIR:=$(shell cd $(dir $(THIS_MAKEFILE_PATH));pwd)
 | 
			
		||||
 | 
			
		||||
# BIN directory
 | 
			
		||||
BIN := $(THIS_DIR)/node_modules/.bin
 | 
			
		||||
 | 
			
		||||
# applications
 | 
			
		||||
NODE ?= $(shell which node)
 | 
			
		||||
NPM ?= $(NODE) $(shell which npm)
 | 
			
		||||
BROWSERIFY ?= $(NODE) $(BIN)/browserify
 | 
			
		||||
 | 
			
		||||
all: dist/debug.js
 | 
			
		||||
 | 
			
		||||
install: node_modules
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
	@rm -rf node_modules dist
 | 
			
		||||
 | 
			
		||||
dist:
 | 
			
		||||
	@mkdir -p $@
 | 
			
		||||
 | 
			
		||||
dist/debug.js: node_modules browser.js debug.js dist
 | 
			
		||||
	@$(BROWSERIFY) \
 | 
			
		||||
		--standalone debug \
 | 
			
		||||
		. > $@
 | 
			
		||||
 | 
			
		||||
node_modules: package.json
 | 
			
		||||
	@NODE_ENV= $(NPM) install
 | 
			
		||||
	@touch node_modules
 | 
			
		||||
 | 
			
		||||
.PHONY: all install clean
 | 
			
		||||
							
								
								
									
										178
									
								
								server/node_modules/monk/node_modules/debug/Readme.md
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										178
									
								
								server/node_modules/monk/node_modules/debug/Readme.md
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,178 @@
 | 
			
		||||
# debug
 | 
			
		||||
 | 
			
		||||
  tiny node.js debugging utility modelled after node core's debugging technique.
 | 
			
		||||
 | 
			
		||||
## Installation
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
$ npm install debug
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Usage
 | 
			
		||||
 | 
			
		||||
 With `debug` you simply invoke the exported function to generate your debug function, passing it a name which will determine if a noop function is returned, or a decorated `console.error`, so all of the `console` format string goodies you're used to work fine. A unique color is selected per-function for visibility.
 | 
			
		||||
 | 
			
		||||
Example _app.js_:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
var debug = require('debug')('http')
 | 
			
		||||
  , http = require('http')
 | 
			
		||||
  , name = 'My App';
 | 
			
		||||
 | 
			
		||||
// fake app
 | 
			
		||||
 | 
			
		||||
debug('booting %s', name);
 | 
			
		||||
 | 
			
		||||
http.createServer(function(req, res){
 | 
			
		||||
  debug(req.method + ' ' + req.url);
 | 
			
		||||
  res.end('hello\n');
 | 
			
		||||
}).listen(3000, function(){
 | 
			
		||||
  debug('listening');
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// fake worker of some kind
 | 
			
		||||
 | 
			
		||||
require('./worker');
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Example _worker.js_:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
var debug = require('debug')('worker');
 | 
			
		||||
 | 
			
		||||
setInterval(function(){
 | 
			
		||||
  debug('doing some work');
 | 
			
		||||
}, 1000);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 The __DEBUG__ environment variable is then used to enable these based on space or comma-delimited names. Here are some examples:
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
#### Windows note
 | 
			
		||||
 | 
			
		||||
 On Windows the environment variable is set using the `set` command. 
 | 
			
		||||
 
 | 
			
		||||
 ```cmd
 | 
			
		||||
 set DEBUG=*,-not_this
 | 
			
		||||
 ```
 | 
			
		||||
 | 
			
		||||
Then, run the program to be debugged as usual.
 | 
			
		||||
 | 
			
		||||
## Millisecond diff
 | 
			
		||||
 | 
			
		||||
  When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls.
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  When stdout is not a TTY, `Date#toUTCString()` is used, making it more useful for logging the debug information as shown below:
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
## Conventions
 | 
			
		||||
 | 
			
		||||
 If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser".
 | 
			
		||||
 | 
			
		||||
## Wildcards
 | 
			
		||||
 | 
			
		||||
  The `*` character may be used as a wildcard. Suppose for example your library has debuggers named "connect:bodyParser", "connect:compress", "connect:session", instead of listing all three with `DEBUG=connect:bodyParser,connect.compress,connect:session`, you may simply do `DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`.
 | 
			
		||||
 | 
			
		||||
  You can also exclude specific debuggers by prefixing them with a "-" character.  For example, `DEBUG=*,-connect:*` would include all debuggers except those starting with "connect:".
 | 
			
		||||
 | 
			
		||||
## Browser support
 | 
			
		||||
 | 
			
		||||
  Debug works in the browser as well, currently persisted by `localStorage`. Consider the situation shown below where you have `worker:a` and `worker:b`, and wish to debug both. Somewhere in the code on your page, include:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
window.myDebug = require("debug");
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
  ("debug" is a global object in the browser so we give this object a different name.) When your page is open in the browser, type the following in the console:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
myDebug.enable("worker:*")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
  Refresh the page. Debug output will continue to be sent to the console until it is disabled by typing `myDebug.disable()` in the console.
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
a = debug('worker:a');
 | 
			
		||||
b = debug('worker:b');
 | 
			
		||||
 | 
			
		||||
setInterval(function(){
 | 
			
		||||
  a('doing some work');
 | 
			
		||||
}, 1000);
 | 
			
		||||
 | 
			
		||||
setInterval(function(){
 | 
			
		||||
  b('doing some work');
 | 
			
		||||
}, 1200);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Web Inspector Colors
 | 
			
		||||
 | 
			
		||||
  Colors are also enabled on "Web Inspectors" that understand the `%c` formatting
 | 
			
		||||
  option. These are WebKit web inspectors, Firefox ([since version
 | 
			
		||||
  31](https://hacks.mozilla.org/2014/05/editable-box-model-multiple-selection-sublime-text-keys-much-more-firefox-developer-tools-episode-31/))
 | 
			
		||||
  and the Firebug plugin for Firefox (any version).
 | 
			
		||||
 | 
			
		||||
  Colored output looks something like:
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
### stderr vs stdout
 | 
			
		||||
 | 
			
		||||
You can set an alternative logging method per-namespace by overriding the `log` method on a per-namespace or globally:
 | 
			
		||||
 | 
			
		||||
Example _stdout.js_:
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
var debug = require('debug');
 | 
			
		||||
var error = debug('app:error');
 | 
			
		||||
 | 
			
		||||
// by default stderr is used
 | 
			
		||||
error('goes to stderr!');
 | 
			
		||||
 | 
			
		||||
var log = debug('app:log');
 | 
			
		||||
// set this namespace to log via console.log
 | 
			
		||||
log.log = console.log.bind(console); // don't forget to bind to console!
 | 
			
		||||
log('goes to stdout');
 | 
			
		||||
error('still goes to stderr!');
 | 
			
		||||
 | 
			
		||||
// set all output to go via console.info
 | 
			
		||||
// overrides all per-namespace log settings
 | 
			
		||||
debug.log = console.info.bind(console);
 | 
			
		||||
error('now goes to stdout via console.info');
 | 
			
		||||
log('still goes to stdout, but via console.info now');
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Authors
 | 
			
		||||
 | 
			
		||||
 - TJ Holowaychuk
 | 
			
		||||
 - Nathan Rajlich
 | 
			
		||||
 | 
			
		||||
## License
 | 
			
		||||
 | 
			
		||||
(The MIT License)
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2014 TJ Holowaychuk <tj@vision-media.ca>
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining
 | 
			
		||||
a copy of this software and associated documentation files (the
 | 
			
		||||
'Software'), to deal in the Software without restriction, including
 | 
			
		||||
without limitation the rights to use, copy, modify, merge, publish,
 | 
			
		||||
distribute, sublicense, and/or sell copies of the Software, and to
 | 
			
		||||
permit persons to whom the Software is furnished to do so, subject to
 | 
			
		||||
the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be
 | 
			
		||||
included in all copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
 | 
			
		||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
			
		||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | 
			
		||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
			
		||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 | 
			
		||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 | 
			
		||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
							
								
								
									
										28
									
								
								server/node_modules/monk/node_modules/debug/bower.json
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										28
									
								
								server/node_modules/monk/node_modules/debug/bower.json
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "visionmedia-debug",
 | 
			
		||||
  "main": "dist/debug.js",
 | 
			
		||||
  "version": "2.1.3",
 | 
			
		||||
  "homepage": "https://github.com/visionmedia/debug",
 | 
			
		||||
  "authors": [
 | 
			
		||||
    "TJ Holowaychuk <tj@vision-media.ca>"
 | 
			
		||||
  ],
 | 
			
		||||
  "description": "visionmedia-debug",
 | 
			
		||||
  "moduleType": [
 | 
			
		||||
    "amd",
 | 
			
		||||
    "es6",
 | 
			
		||||
    "globals",
 | 
			
		||||
    "node"
 | 
			
		||||
  ],
 | 
			
		||||
  "keywords": [
 | 
			
		||||
    "visionmedia",
 | 
			
		||||
    "debug"
 | 
			
		||||
  ],
 | 
			
		||||
  "license": "MIT",
 | 
			
		||||
  "ignore": [
 | 
			
		||||
    "**/.*",
 | 
			
		||||
    "node_modules",
 | 
			
		||||
    "bower_components",
 | 
			
		||||
    "test",
 | 
			
		||||
    "tests"
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										175
									
								
								server/node_modules/monk/node_modules/debug/browser.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										175
									
								
								server/node_modules/monk/node_modules/debug/browser.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,175 @@
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This is the web browser implementation of `debug()`.
 | 
			
		||||
 *
 | 
			
		||||
 * Expose `debug()` as the module.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
exports = module.exports = require('./debug');
 | 
			
		||||
exports.log = log;
 | 
			
		||||
exports.formatArgs = formatArgs;
 | 
			
		||||
exports.save = save;
 | 
			
		||||
exports.load = load;
 | 
			
		||||
exports.useColors = useColors;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Use chrome.storage.local if we are in an app
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
var storage;
 | 
			
		||||
 | 
			
		||||
if (typeof chrome !== 'undefined' && typeof chrome.storage !== 'undefined')
 | 
			
		||||
  storage = chrome.storage.local;
 | 
			
		||||
else
 | 
			
		||||
  storage = localstorage();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Colors.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
exports.colors = [
 | 
			
		||||
  'lightseagreen',
 | 
			
		||||
  'forestgreen',
 | 
			
		||||
  'goldenrod',
 | 
			
		||||
  'dodgerblue',
 | 
			
		||||
  'darkorchid',
 | 
			
		||||
  'crimson'
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Currently only WebKit-based Web Inspectors, Firefox >= v31,
 | 
			
		||||
 * and the Firebug extension (any Firefox version) are known
 | 
			
		||||
 * to support "%c" CSS customizations.
 | 
			
		||||
 *
 | 
			
		||||
 * TODO: add a `localStorage` variable to explicitly enable/disable colors
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function useColors() {
 | 
			
		||||
  // is webkit? http://stackoverflow.com/a/16459606/376773
 | 
			
		||||
  return ('WebkitAppearance' in document.documentElement.style) ||
 | 
			
		||||
    // is firebug? http://stackoverflow.com/a/398120/376773
 | 
			
		||||
    (window.console && (console.firebug || (console.exception && console.table))) ||
 | 
			
		||||
    // is firefox >= v31?
 | 
			
		||||
    // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
 | 
			
		||||
    (navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
exports.formatters.j = function(v) {
 | 
			
		||||
  return JSON.stringify(v);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Colorize log arguments if enabled.
 | 
			
		||||
 *
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function formatArgs() {
 | 
			
		||||
  var args = arguments;
 | 
			
		||||
  var useColors = this.useColors;
 | 
			
		||||
 | 
			
		||||
  args[0] = (useColors ? '%c' : '')
 | 
			
		||||
    + this.namespace
 | 
			
		||||
    + (useColors ? ' %c' : ' ')
 | 
			
		||||
    + args[0]
 | 
			
		||||
    + (useColors ? '%c ' : ' ')
 | 
			
		||||
    + '+' + exports.humanize(this.diff);
 | 
			
		||||
 | 
			
		||||
  if (!useColors) return args;
 | 
			
		||||
 | 
			
		||||
  var c = 'color: ' + this.color;
 | 
			
		||||
  args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1));
 | 
			
		||||
 | 
			
		||||
  // the final "%c" is somewhat tricky, because there could be other
 | 
			
		||||
  // arguments passed either before or after the %c, so we need to
 | 
			
		||||
  // figure out the correct index to insert the CSS into
 | 
			
		||||
  var index = 0;
 | 
			
		||||
  var lastC = 0;
 | 
			
		||||
  args[0].replace(/%[a-z%]/g, function(match) {
 | 
			
		||||
    if ('%%' === match) return;
 | 
			
		||||
    index++;
 | 
			
		||||
    if ('%c' === match) {
 | 
			
		||||
      // we only are interested in the *last* %c
 | 
			
		||||
      // (the user may have provided their own)
 | 
			
		||||
      lastC = index;
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  args.splice(lastC, 0, c);
 | 
			
		||||
  return args;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Invokes `console.log()` when available.
 | 
			
		||||
 * No-op when `console.log` is not a "function".
 | 
			
		||||
 *
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function log() {
 | 
			
		||||
  // this hackery is required for IE8/9, where
 | 
			
		||||
  // the `console.log` function doesn't have 'apply'
 | 
			
		||||
  return 'object' === typeof console
 | 
			
		||||
    && console.log
 | 
			
		||||
    && Function.prototype.apply.call(console.log, console, arguments);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Save `namespaces`.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {String} namespaces
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function save(namespaces) {
 | 
			
		||||
  try {
 | 
			
		||||
    if (null == namespaces) {
 | 
			
		||||
      storage.removeItem('debug');
 | 
			
		||||
    } else {
 | 
			
		||||
      storage.debug = namespaces;
 | 
			
		||||
    }
 | 
			
		||||
  } catch(e) {}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Load `namespaces`.
 | 
			
		||||
 *
 | 
			
		||||
 * @return {String} returns the previously persisted debug modes
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function load() {
 | 
			
		||||
  var r;
 | 
			
		||||
  try {
 | 
			
		||||
    r = storage.debug;
 | 
			
		||||
  } catch(e) {}
 | 
			
		||||
  return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Enable namespaces listed in `localStorage.debug` initially.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
exports.enable(load());
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Localstorage attempts to return the localstorage.
 | 
			
		||||
 *
 | 
			
		||||
 * This is necessary because safari throws
 | 
			
		||||
 * when a user disables cookies/localstorage
 | 
			
		||||
 * and you attempt to access it.
 | 
			
		||||
 *
 | 
			
		||||
 * @return {LocalStorage}
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function localstorage(){
 | 
			
		||||
  try {
 | 
			
		||||
    return window.localStorage;
 | 
			
		||||
  } catch (e) {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										19
									
								
								server/node_modules/monk/node_modules/debug/component.json
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										19
									
								
								server/node_modules/monk/node_modules/debug/component.json
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "debug",
 | 
			
		||||
  "repo": "visionmedia/debug",
 | 
			
		||||
  "description": "small debugging utility",
 | 
			
		||||
  "version": "2.1.3",
 | 
			
		||||
  "keywords": [
 | 
			
		||||
    "debug",
 | 
			
		||||
    "log",
 | 
			
		||||
    "debugger"
 | 
			
		||||
  ],
 | 
			
		||||
  "main": "browser.js",
 | 
			
		||||
  "scripts": [
 | 
			
		||||
    "browser.js",
 | 
			
		||||
    "debug.js"
 | 
			
		||||
  ],
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "rauchg/ms.js": "0.7.0"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										197
									
								
								server/node_modules/monk/node_modules/debug/debug.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										197
									
								
								server/node_modules/monk/node_modules/debug/debug.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,197 @@
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This is the common logic for both the Node.js and web browser
 | 
			
		||||
 * implementations of `debug()`.
 | 
			
		||||
 *
 | 
			
		||||
 * Expose `debug()` as the module.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
exports = module.exports = debug;
 | 
			
		||||
exports.coerce = coerce;
 | 
			
		||||
exports.disable = disable;
 | 
			
		||||
exports.enable = enable;
 | 
			
		||||
exports.enabled = enabled;
 | 
			
		||||
exports.humanize = require('ms');
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The currently active debug mode names, and names to skip.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
exports.names = [];
 | 
			
		||||
exports.skips = [];
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Map of special "%n" handling functions, for the debug "format" argument.
 | 
			
		||||
 *
 | 
			
		||||
 * Valid key names are a single, lowercased letter, i.e. "n".
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
exports.formatters = {};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Previously assigned color.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
var prevColor = 0;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Previous log timestamp.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
var prevTime;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Select a color.
 | 
			
		||||
 *
 | 
			
		||||
 * @return {Number}
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function selectColor() {
 | 
			
		||||
  return exports.colors[prevColor++ % exports.colors.length];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create a debugger with the given `namespace`.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {String} namespace
 | 
			
		||||
 * @return {Function}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function debug(namespace) {
 | 
			
		||||
 | 
			
		||||
  // define the `disabled` version
 | 
			
		||||
  function disabled() {
 | 
			
		||||
  }
 | 
			
		||||
  disabled.enabled = false;
 | 
			
		||||
 | 
			
		||||
  // define the `enabled` version
 | 
			
		||||
  function enabled() {
 | 
			
		||||
 | 
			
		||||
    var self = enabled;
 | 
			
		||||
 | 
			
		||||
    // set `diff` timestamp
 | 
			
		||||
    var curr = +new Date();
 | 
			
		||||
    var ms = curr - (prevTime || curr);
 | 
			
		||||
    self.diff = ms;
 | 
			
		||||
    self.prev = prevTime;
 | 
			
		||||
    self.curr = curr;
 | 
			
		||||
    prevTime = curr;
 | 
			
		||||
 | 
			
		||||
    // add the `color` if not set
 | 
			
		||||
    if (null == self.useColors) self.useColors = exports.useColors();
 | 
			
		||||
    if (null == self.color && self.useColors) self.color = selectColor();
 | 
			
		||||
 | 
			
		||||
    var args = Array.prototype.slice.call(arguments);
 | 
			
		||||
 | 
			
		||||
    args[0] = exports.coerce(args[0]);
 | 
			
		||||
 | 
			
		||||
    if ('string' !== typeof args[0]) {
 | 
			
		||||
      // anything else let's inspect with %o
 | 
			
		||||
      args = ['%o'].concat(args);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // apply any `formatters` transformations
 | 
			
		||||
    var index = 0;
 | 
			
		||||
    args[0] = args[0].replace(/%([a-z%])/g, function(match, format) {
 | 
			
		||||
      // if we encounter an escaped % then don't increase the array index
 | 
			
		||||
      if (match === '%%') return match;
 | 
			
		||||
      index++;
 | 
			
		||||
      var formatter = exports.formatters[format];
 | 
			
		||||
      if ('function' === typeof formatter) {
 | 
			
		||||
        var val = args[index];
 | 
			
		||||
        match = formatter.call(self, val);
 | 
			
		||||
 | 
			
		||||
        // now we need to remove `args[index]` since it's inlined in the `format`
 | 
			
		||||
        args.splice(index, 1);
 | 
			
		||||
        index--;
 | 
			
		||||
      }
 | 
			
		||||
      return match;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    if ('function' === typeof exports.formatArgs) {
 | 
			
		||||
      args = exports.formatArgs.apply(self, args);
 | 
			
		||||
    }
 | 
			
		||||
    var logFn = enabled.log || exports.log || console.log.bind(console);
 | 
			
		||||
    logFn.apply(self, args);
 | 
			
		||||
  }
 | 
			
		||||
  enabled.enabled = true;
 | 
			
		||||
 | 
			
		||||
  var fn = exports.enabled(namespace) ? enabled : disabled;
 | 
			
		||||
 | 
			
		||||
  fn.namespace = namespace;
 | 
			
		||||
 | 
			
		||||
  return fn;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Enables a debug mode by namespaces. This can include modes
 | 
			
		||||
 * separated by a colon and wildcards.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {String} namespaces
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function enable(namespaces) {
 | 
			
		||||
  exports.save(namespaces);
 | 
			
		||||
 | 
			
		||||
  var split = (namespaces || '').split(/[\s,]+/);
 | 
			
		||||
  var len = split.length;
 | 
			
		||||
 | 
			
		||||
  for (var i = 0; i < len; i++) {
 | 
			
		||||
    if (!split[i]) continue; // ignore empty strings
 | 
			
		||||
    namespaces = split[i].replace(/\*/g, '.*?');
 | 
			
		||||
    if (namespaces[0] === '-') {
 | 
			
		||||
      exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
 | 
			
		||||
    } else {
 | 
			
		||||
      exports.names.push(new RegExp('^' + namespaces + '$'));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Disable debug output.
 | 
			
		||||
 *
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function disable() {
 | 
			
		||||
  exports.enable('');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns true if the given mode name is enabled, false otherwise.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {String} name
 | 
			
		||||
 * @return {Boolean}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function enabled(name) {
 | 
			
		||||
  var i, len;
 | 
			
		||||
  for (i = 0, len = exports.skips.length; i < len; i++) {
 | 
			
		||||
    if (exports.skips[i].test(name)) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  for (i = 0, len = exports.names.length; i < len; i++) {
 | 
			
		||||
    if (exports.names[i].test(name)) {
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Coerce `val`.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Mixed} val
 | 
			
		||||
 * @return {Mixed}
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function coerce(val) {
 | 
			
		||||
  if (val instanceof Error) return val.stack || val.message;
 | 
			
		||||
  return val;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										209
									
								
								server/node_modules/monk/node_modules/debug/node.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										209
									
								
								server/node_modules/monk/node_modules/debug/node.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,209 @@
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Module dependencies.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
var tty = require('tty');
 | 
			
		||||
var util = require('util');
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This is the Node.js implementation of `debug()`.
 | 
			
		||||
 *
 | 
			
		||||
 * Expose `debug()` as the module.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
exports = module.exports = require('./debug');
 | 
			
		||||
exports.log = log;
 | 
			
		||||
exports.formatArgs = formatArgs;
 | 
			
		||||
exports.save = save;
 | 
			
		||||
exports.load = load;
 | 
			
		||||
exports.useColors = useColors;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Colors.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
exports.colors = [6, 2, 3, 4, 5, 1];
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The file descriptor to write the `debug()` calls to.
 | 
			
		||||
 * Set the `DEBUG_FD` env variable to override with another value. i.e.:
 | 
			
		||||
 *
 | 
			
		||||
 *   $ DEBUG_FD=3 node script.js 3>debug.log
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
var fd = parseInt(process.env.DEBUG_FD, 10) || 2;
 | 
			
		||||
var stream = 1 === fd ? process.stdout :
 | 
			
		||||
             2 === fd ? process.stderr :
 | 
			
		||||
             createWritableStdioStream(fd);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Is stdout a TTY? Colored output is enabled when `true`.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function useColors() {
 | 
			
		||||
  var debugColors = (process.env.DEBUG_COLORS || '').trim().toLowerCase();
 | 
			
		||||
  if (0 === debugColors.length) {
 | 
			
		||||
    return tty.isatty(fd);
 | 
			
		||||
  } else {
 | 
			
		||||
    return '0' !== debugColors
 | 
			
		||||
        && 'no' !== debugColors
 | 
			
		||||
        && 'false' !== debugColors
 | 
			
		||||
        && 'disabled' !== debugColors;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Map %o to `util.inspect()`, since Node doesn't do that out of the box.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
var inspect = (4 === util.inspect.length ?
 | 
			
		||||
  // node <= 0.8.x
 | 
			
		||||
  function (v, colors) {
 | 
			
		||||
    return util.inspect(v, void 0, void 0, colors);
 | 
			
		||||
  } :
 | 
			
		||||
  // node > 0.8.x
 | 
			
		||||
  function (v, colors) {
 | 
			
		||||
    return util.inspect(v, { colors: colors });
 | 
			
		||||
  }
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
exports.formatters.o = function(v) {
 | 
			
		||||
  return inspect(v, this.useColors)
 | 
			
		||||
    .replace(/\s*\n\s*/g, ' ');
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Adds ANSI color escape codes if enabled.
 | 
			
		||||
 *
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function formatArgs() {
 | 
			
		||||
  var args = arguments;
 | 
			
		||||
  var useColors = this.useColors;
 | 
			
		||||
  var name = this.namespace;
 | 
			
		||||
 | 
			
		||||
  if (useColors) {
 | 
			
		||||
    var c = this.color;
 | 
			
		||||
 | 
			
		||||
    args[0] = '  \u001b[3' + c + ';1m' + name + ' '
 | 
			
		||||
      + '\u001b[0m'
 | 
			
		||||
      + args[0] + '\u001b[3' + c + 'm'
 | 
			
		||||
      + ' +' + exports.humanize(this.diff) + '\u001b[0m';
 | 
			
		||||
  } else {
 | 
			
		||||
    args[0] = new Date().toUTCString()
 | 
			
		||||
      + ' ' + name + ' ' + args[0];
 | 
			
		||||
  }
 | 
			
		||||
  return args;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Invokes `console.error()` with the specified arguments.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function log() {
 | 
			
		||||
  return stream.write(util.format.apply(this, arguments) + '\n');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Save `namespaces`.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {String} namespaces
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function save(namespaces) {
 | 
			
		||||
  if (null == namespaces) {
 | 
			
		||||
    // If you set a process.env field to null or undefined, it gets cast to the
 | 
			
		||||
    // string 'null' or 'undefined'. Just delete instead.
 | 
			
		||||
    delete process.env.DEBUG;
 | 
			
		||||
  } else {
 | 
			
		||||
    process.env.DEBUG = namespaces;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Load `namespaces`.
 | 
			
		||||
 *
 | 
			
		||||
 * @return {String} returns the previously persisted debug modes
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function load() {
 | 
			
		||||
  return process.env.DEBUG;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Copied from `node/src/node.js`.
 | 
			
		||||
 *
 | 
			
		||||
 * XXX: It's lame that node doesn't expose this API out-of-the-box. It also
 | 
			
		||||
 * relies on the undocumented `tty_wrap.guessHandleType()` which is also lame.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function createWritableStdioStream (fd) {
 | 
			
		||||
  var stream;
 | 
			
		||||
  var tty_wrap = process.binding('tty_wrap');
 | 
			
		||||
 | 
			
		||||
  // Note stream._type is used for test-module-load-list.js
 | 
			
		||||
 | 
			
		||||
  switch (tty_wrap.guessHandleType(fd)) {
 | 
			
		||||
    case 'TTY':
 | 
			
		||||
      stream = new tty.WriteStream(fd);
 | 
			
		||||
      stream._type = 'tty';
 | 
			
		||||
 | 
			
		||||
      // Hack to have stream not keep the event loop alive.
 | 
			
		||||
      // See https://github.com/joyent/node/issues/1726
 | 
			
		||||
      if (stream._handle && stream._handle.unref) {
 | 
			
		||||
        stream._handle.unref();
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case 'FILE':
 | 
			
		||||
      var fs = require('fs');
 | 
			
		||||
      stream = new fs.SyncWriteStream(fd, { autoClose: false });
 | 
			
		||||
      stream._type = 'fs';
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    case 'PIPE':
 | 
			
		||||
    case 'TCP':
 | 
			
		||||
      var net = require('net');
 | 
			
		||||
      stream = new net.Socket({
 | 
			
		||||
        fd: fd,
 | 
			
		||||
        readable: false,
 | 
			
		||||
        writable: true
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      // FIXME Should probably have an option in net.Socket to create a
 | 
			
		||||
      // stream from an existing fd which is writable only. But for now
 | 
			
		||||
      // we'll just add this hack and set the `readable` member to false.
 | 
			
		||||
      // Test: ./node test/fixtures/echo.js < /etc/passwd
 | 
			
		||||
      stream.readable = false;
 | 
			
		||||
      stream.read = null;
 | 
			
		||||
      stream._type = 'pipe';
 | 
			
		||||
 | 
			
		||||
      // FIXME Hack to have stream not keep the event loop alive.
 | 
			
		||||
      // See https://github.com/joyent/node/issues/1726
 | 
			
		||||
      if (stream._handle && stream._handle.unref) {
 | 
			
		||||
        stream._handle.unref();
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      // Probably an error on in uv_guess_handle()
 | 
			
		||||
      throw new Error('Implement me. Unknown stream file type!');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // For supporting legacy API we put the FD here.
 | 
			
		||||
  stream.fd = fd;
 | 
			
		||||
 | 
			
		||||
  stream._isStdio = true;
 | 
			
		||||
 | 
			
		||||
  return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Enable namespaces listed in `process.env.DEBUG` initially.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
exports.enable(load());
 | 
			
		||||
							
								
								
									
										5
									
								
								server/node_modules/monk/node_modules/debug/node_modules/ms/.npmignore
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										5
									
								
								server/node_modules/monk/node_modules/debug/node_modules/ms/.npmignore
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
node_modules
 | 
			
		||||
test
 | 
			
		||||
History.md
 | 
			
		||||
Makefile
 | 
			
		||||
component.json
 | 
			
		||||
							
								
								
									
										20
									
								
								server/node_modules/monk/node_modules/debug/node_modules/ms/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										20
									
								
								server/node_modules/monk/node_modules/debug/node_modules/ms/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
(The MIT License)
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2014 Guillermo Rauch <rauchg@gmail.com>
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
the Software without restriction, including without limitation the rights to
 | 
			
		||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
							
								
								
									
										35
									
								
								server/node_modules/monk/node_modules/debug/node_modules/ms/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										35
									
								
								server/node_modules/monk/node_modules/debug/node_modules/ms/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
# ms.js: miliseconds conversion utility
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
ms('2 days')  // 172800000
 | 
			
		||||
ms('1d')      // 86400000
 | 
			
		||||
ms('10h')     // 36000000
 | 
			
		||||
ms('2.5 hrs') // 9000000
 | 
			
		||||
ms('2h')      // 7200000
 | 
			
		||||
ms('1m')      // 60000
 | 
			
		||||
ms('5s')      // 5000
 | 
			
		||||
ms('100')     // 100
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
ms(60000)             // "1m"
 | 
			
		||||
ms(2 * 60000)         // "2m"
 | 
			
		||||
ms(ms('10 hours'))    // "10h"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```js
 | 
			
		||||
ms(60000, { long: true })             // "1 minute"
 | 
			
		||||
ms(2 * 60000, { long: true })         // "2 minutes"
 | 
			
		||||
ms(ms('10 hours'), { long: true })    // "10 hours"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
- Node/Browser compatible. Published as [`ms`](https://www.npmjs.org/package/ms) in [NPM](nodejs.org/download).
 | 
			
		||||
- If a number is supplied to `ms`, a string with a unit is returned.
 | 
			
		||||
- If a string that contains the number is supplied, it returns it as
 | 
			
		||||
a number (e.g: it returns `100` for `'100'`).
 | 
			
		||||
- If you pass a string with a number and a valid unit, the number of
 | 
			
		||||
equivalent ms is returned.
 | 
			
		||||
 | 
			
		||||
## License
 | 
			
		||||
 | 
			
		||||
MIT
 | 
			
		||||
							
								
								
									
										123
									
								
								server/node_modules/monk/node_modules/debug/node_modules/ms/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										123
									
								
								server/node_modules/monk/node_modules/debug/node_modules/ms/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,123 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Helpers.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
var s = 1000;
 | 
			
		||||
var m = s * 60;
 | 
			
		||||
var h = m * 60;
 | 
			
		||||
var d = h * 24;
 | 
			
		||||
var y = d * 365.25;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Parse or format the given `val`.
 | 
			
		||||
 *
 | 
			
		||||
 * Options:
 | 
			
		||||
 *
 | 
			
		||||
 *  - `long` verbose formatting [false]
 | 
			
		||||
 *
 | 
			
		||||
 * @param {String|Number} val
 | 
			
		||||
 * @param {Object} options
 | 
			
		||||
 * @return {String|Number}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
module.exports = function(val, options){
 | 
			
		||||
  options = options || {};
 | 
			
		||||
  if ('string' == typeof val) return parse(val);
 | 
			
		||||
  return options.long
 | 
			
		||||
    ? long(val)
 | 
			
		||||
    : short(val);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Parse the given `str` and return milliseconds.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {String} str
 | 
			
		||||
 * @return {Number}
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function parse(str) {
 | 
			
		||||
  var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str);
 | 
			
		||||
  if (!match) return;
 | 
			
		||||
  var n = parseFloat(match[1]);
 | 
			
		||||
  var type = (match[2] || 'ms').toLowerCase();
 | 
			
		||||
  switch (type) {
 | 
			
		||||
    case 'years':
 | 
			
		||||
    case 'year':
 | 
			
		||||
    case 'yrs':
 | 
			
		||||
    case 'yr':
 | 
			
		||||
    case 'y':
 | 
			
		||||
      return n * y;
 | 
			
		||||
    case 'days':
 | 
			
		||||
    case 'day':
 | 
			
		||||
    case 'd':
 | 
			
		||||
      return n * d;
 | 
			
		||||
    case 'hours':
 | 
			
		||||
    case 'hour':
 | 
			
		||||
    case 'hrs':
 | 
			
		||||
    case 'hr':
 | 
			
		||||
    case 'h':
 | 
			
		||||
      return n * h;
 | 
			
		||||
    case 'minutes':
 | 
			
		||||
    case 'minute':
 | 
			
		||||
    case 'mins':
 | 
			
		||||
    case 'min':
 | 
			
		||||
    case 'm':
 | 
			
		||||
      return n * m;
 | 
			
		||||
    case 'seconds':
 | 
			
		||||
    case 'second':
 | 
			
		||||
    case 'secs':
 | 
			
		||||
    case 'sec':
 | 
			
		||||
    case 's':
 | 
			
		||||
      return n * s;
 | 
			
		||||
    case 'milliseconds':
 | 
			
		||||
    case 'millisecond':
 | 
			
		||||
    case 'msecs':
 | 
			
		||||
    case 'msec':
 | 
			
		||||
    case 'ms':
 | 
			
		||||
      return n;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Short format for `ms`.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Number} ms
 | 
			
		||||
 * @return {String}
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function short(ms) {
 | 
			
		||||
  if (ms >= d) return Math.round(ms / d) + 'd';
 | 
			
		||||
  if (ms >= h) return Math.round(ms / h) + 'h';
 | 
			
		||||
  if (ms >= m) return Math.round(ms / m) + 'm';
 | 
			
		||||
  if (ms >= s) return Math.round(ms / s) + 's';
 | 
			
		||||
  return ms + 'ms';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Long format for `ms`.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Number} ms
 | 
			
		||||
 * @return {String}
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function long(ms) {
 | 
			
		||||
  return plural(ms, d, 'day')
 | 
			
		||||
    || plural(ms, h, 'hour')
 | 
			
		||||
    || plural(ms, m, 'minute')
 | 
			
		||||
    || plural(ms, s, 'second')
 | 
			
		||||
    || ms + ' ms';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Pluralization helper.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function plural(ms, n, name) {
 | 
			
		||||
  if (ms < n) return;
 | 
			
		||||
  if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;
 | 
			
		||||
  return Math.ceil(ms / n) + ' ' + name + 's';
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										47
									
								
								server/node_modules/monk/node_modules/debug/node_modules/ms/package.json
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										47
									
								
								server/node_modules/monk/node_modules/debug/node_modules/ms/package.json
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "ms",
 | 
			
		||||
  "version": "0.7.0",
 | 
			
		||||
  "description": "Tiny ms conversion utility",
 | 
			
		||||
  "repository": {
 | 
			
		||||
    "type": "git",
 | 
			
		||||
    "url": "git://github.com/guille/ms.js.git"
 | 
			
		||||
  },
 | 
			
		||||
  "main": "./index",
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "mocha": "*",
 | 
			
		||||
    "expect.js": "*",
 | 
			
		||||
    "serve": "*"
 | 
			
		||||
  },
 | 
			
		||||
  "component": {
 | 
			
		||||
    "scripts": {
 | 
			
		||||
      "ms/index.js": "index.js"
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "gitHead": "1e9cd9b05ef0dc26f765434d2bfee42394376e52",
 | 
			
		||||
  "bugs": {
 | 
			
		||||
    "url": "https://github.com/guille/ms.js/issues"
 | 
			
		||||
  },
 | 
			
		||||
  "homepage": "https://github.com/guille/ms.js",
 | 
			
		||||
  "_id": "ms@0.7.0",
 | 
			
		||||
  "scripts": {},
 | 
			
		||||
  "_shasum": "865be94c2e7397ad8a57da6a633a6e2f30798b83",
 | 
			
		||||
  "_from": "ms@0.7.0",
 | 
			
		||||
  "_npmVersion": "1.4.21",
 | 
			
		||||
  "_npmUser": {
 | 
			
		||||
    "name": "rauchg",
 | 
			
		||||
    "email": "rauchg@gmail.com"
 | 
			
		||||
  },
 | 
			
		||||
  "maintainers": [
 | 
			
		||||
    {
 | 
			
		||||
      "name": "rauchg",
 | 
			
		||||
      "email": "rauchg@gmail.com"
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "dist": {
 | 
			
		||||
    "shasum": "865be94c2e7397ad8a57da6a633a6e2f30798b83",
 | 
			
		||||
    "tarball": "http://registry.npmjs.org/ms/-/ms-0.7.0.tgz"
 | 
			
		||||
  },
 | 
			
		||||
  "directories": {},
 | 
			
		||||
  "_resolved": "https://registry.npmjs.org/ms/-/ms-0.7.0.tgz",
 | 
			
		||||
  "readme": "ERROR: No README data found!"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										73
									
								
								server/node_modules/monk/node_modules/debug/package.json
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										73
									
								
								server/node_modules/monk/node_modules/debug/package.json
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,73 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "debug",
 | 
			
		||||
  "version": "2.1.3",
 | 
			
		||||
  "repository": {
 | 
			
		||||
    "type": "git",
 | 
			
		||||
    "url": "git://github.com/visionmedia/debug.git"
 | 
			
		||||
  },
 | 
			
		||||
  "description": "small debugging utility",
 | 
			
		||||
  "keywords": [
 | 
			
		||||
    "debug",
 | 
			
		||||
    "log",
 | 
			
		||||
    "debugger"
 | 
			
		||||
  ],
 | 
			
		||||
  "author": {
 | 
			
		||||
    "name": "TJ Holowaychuk",
 | 
			
		||||
    "email": "tj@vision-media.ca"
 | 
			
		||||
  },
 | 
			
		||||
  "contributors": [
 | 
			
		||||
    {
 | 
			
		||||
      "name": "Nathan Rajlich",
 | 
			
		||||
      "email": "nathan@tootallnate.net",
 | 
			
		||||
      "url": "http://n8.io"
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "license": "MIT",
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "ms": "0.7.0"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "browserify": "9.0.3",
 | 
			
		||||
    "mocha": "*"
 | 
			
		||||
  },
 | 
			
		||||
  "main": "./node.js",
 | 
			
		||||
  "browser": "./browser.js",
 | 
			
		||||
  "component": {
 | 
			
		||||
    "scripts": {
 | 
			
		||||
      "debug/index.js": "browser.js",
 | 
			
		||||
      "debug/debug.js": "debug.js"
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "gitHead": "0a8e4b7e0d2d1b55ef4e7422498ca24c677ae63a",
 | 
			
		||||
  "bugs": {
 | 
			
		||||
    "url": "https://github.com/visionmedia/debug/issues"
 | 
			
		||||
  },
 | 
			
		||||
  "homepage": "https://github.com/visionmedia/debug",
 | 
			
		||||
  "_id": "debug@2.1.3",
 | 
			
		||||
  "scripts": {},
 | 
			
		||||
  "_shasum": "ce8ab1b5ee8fbee2bfa3b633cab93d366b63418e",
 | 
			
		||||
  "_from": "debug@*",
 | 
			
		||||
  "_npmVersion": "2.5.1",
 | 
			
		||||
  "_nodeVersion": "0.12.0",
 | 
			
		||||
  "_npmUser": {
 | 
			
		||||
    "name": "tootallnate",
 | 
			
		||||
    "email": "nathan@tootallnate.net"
 | 
			
		||||
  },
 | 
			
		||||
  "maintainers": [
 | 
			
		||||
    {
 | 
			
		||||
      "name": "tjholowaychuk",
 | 
			
		||||
      "email": "tj@vision-media.ca"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "name": "tootallnate",
 | 
			
		||||
      "email": "nathan@tootallnate.net"
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "dist": {
 | 
			
		||||
    "shasum": "ce8ab1b5ee8fbee2bfa3b633cab93d366b63418e",
 | 
			
		||||
    "tarball": "http://registry.npmjs.org/debug/-/debug-2.1.3.tgz"
 | 
			
		||||
  },
 | 
			
		||||
  "directories": {},
 | 
			
		||||
  "_resolved": "https://registry.npmjs.org/debug/-/debug-2.1.3.tgz",
 | 
			
		||||
  "readme": "ERROR: No README data found!"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										0
									
								
								server/node_modules/monk/node_modules/mongodb/.gitmodules
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										0
									
								
								server/node_modules/monk/node_modules/mongodb/.gitmodules
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
								
								
									
										10
									
								
								server/node_modules/monk/node_modules/mongodb/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										10
									
								
								server/node_modules/monk/node_modules/mongodb/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
language: node_js
 | 
			
		||||
node_js:
 | 
			
		||||
  - 0.10
 | 
			
		||||
  - 0.11
 | 
			
		||||
sudo: false
 | 
			
		||||
env:
 | 
			
		||||
  - MONGODB_VERSION=2.2.x
 | 
			
		||||
  - MONGODB_VERSION=2.4.x
 | 
			
		||||
  - MONGODB_VERSION=2.6.x
 | 
			
		||||
  - MONGODB_VERSION=3.0.x
 | 
			
		||||
							
								
								
									
										23
									
								
								server/node_modules/monk/node_modules/mongodb/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										23
									
								
								server/node_modules/monk/node_modules/mongodb/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
## Contributing to the driver
 | 
			
		||||
 | 
			
		||||
### Bugfixes
 | 
			
		||||
 | 
			
		||||
- Before starting to write code, look for existing [tickets](https://jira.mongodb.org/browse/NODE) or [create one](https://jira.mongodb.org/secure/CreateIssue!default.jspa) for your specific issue under the "Node Driver" project. That way you avoid working on something that might not be of interest or that has been addressed already in a different branch.
 | 
			
		||||
- Fork the [repo](https://github.com/mongodb/node-mongodb-native) _or_ for small documentation changes, navigate to the source on github and click the [Edit](https://github.com/blog/844-forking-with-the-edit-button) button.
 | 
			
		||||
- Follow the general coding style of the rest of the project:
 | 
			
		||||
  - 2 space tabs
 | 
			
		||||
  - no trailing whitespace
 | 
			
		||||
  - comma last
 | 
			
		||||
  - inline documentation for new methods, class members, etc
 | 
			
		||||
  - 0 space between conditionals/functions, and their parenthesis and curly braces
 | 
			
		||||
    - `if(..) {`
 | 
			
		||||
    - `for(..) {`
 | 
			
		||||
    - `while(..) {`
 | 
			
		||||
    - `function(err) {`
 | 
			
		||||
- Write tests and make sure they pass (execute `npm test` from the cmd line to run the test suite).
 | 
			
		||||
 | 
			
		||||
### Documentation
 | 
			
		||||
 | 
			
		||||
To contribute to the [API documentation](http://mongodb.github.com/node-mongodb-native/) just make your changes to the inline documentation of the appropriate [source code](https://github.com/mongodb/node-mongodb-native/tree/master/docs) in the master branch and submit a [pull request](https://help.github.com/articles/using-pull-requests/). You might also use the github [Edit](https://github.com/blog/844-forking-with-the-edit-button) button.
 | 
			
		||||
 | 
			
		||||
If you'd like to preview your documentation changes, first commit your changes to your local master branch, then execute `make generate_docs`. Make sure you have the python documentation framework sphinx installed `easy_install sphinx`. The docs are generated under `docs/build'. If all looks good, submit a [pull request](https://help.github.com/articles/using-pull-requests/) to the master branch with your changes.
 | 
			
		||||
							
								
								
									
										201
									
								
								server/node_modules/monk/node_modules/mongodb/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										201
									
								
								server/node_modules/monk/node_modules/mongodb/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,201 @@
 | 
			
		||||
                                 Apache License
 | 
			
		||||
                           Version 2.0, January 2004
 | 
			
		||||
                        http://www.apache.org/licenses/
 | 
			
		||||
 | 
			
		||||
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
			
		||||
 | 
			
		||||
   1. Definitions.
 | 
			
		||||
 | 
			
		||||
      "License" shall mean the terms and conditions for use, reproduction,
 | 
			
		||||
      and distribution as defined by Sections 1 through 9 of this document.
 | 
			
		||||
 | 
			
		||||
      "Licensor" shall mean the copyright owner or entity authorized by
 | 
			
		||||
      the copyright owner that is granting the License.
 | 
			
		||||
 | 
			
		||||
      "Legal Entity" shall mean the union of the acting entity and all
 | 
			
		||||
      other entities that control, are controlled by, or are under common
 | 
			
		||||
      control with that entity. For the purposes of this definition,
 | 
			
		||||
      "control" means (i) the power, direct or indirect, to cause the
 | 
			
		||||
      direction or management of such entity, whether by contract or
 | 
			
		||||
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
			
		||||
      outstanding shares, or (iii) beneficial ownership of such entity.
 | 
			
		||||
 | 
			
		||||
      "You" (or "Your") shall mean an individual or Legal Entity
 | 
			
		||||
      exercising permissions granted by this License.
 | 
			
		||||
 | 
			
		||||
      "Source" form shall mean the preferred form for making modifications,
 | 
			
		||||
      including but not limited to software source code, documentation
 | 
			
		||||
      source, and configuration files.
 | 
			
		||||
 | 
			
		||||
      "Object" form shall mean any form resulting from mechanical
 | 
			
		||||
      transformation or translation of a Source form, including but
 | 
			
		||||
      not limited to compiled object code, generated documentation,
 | 
			
		||||
      and conversions to other media types.
 | 
			
		||||
 | 
			
		||||
      "Work" shall mean the work of authorship, whether in Source or
 | 
			
		||||
      Object form, made available under the License, as indicated by a
 | 
			
		||||
      copyright notice that is included in or attached to the work
 | 
			
		||||
      (an example is provided in the Appendix below).
 | 
			
		||||
 | 
			
		||||
      "Derivative Works" shall mean any work, whether in Source or Object
 | 
			
		||||
      form, that is based on (or derived from) the Work and for which the
 | 
			
		||||
      editorial revisions, annotations, elaborations, or other modifications
 | 
			
		||||
      represent, as a whole, an original work of authorship. For the purposes
 | 
			
		||||
      of this License, Derivative Works shall not include works that remain
 | 
			
		||||
      separable from, or merely link (or bind by name) to the interfaces of,
 | 
			
		||||
      the Work and Derivative Works thereof.
 | 
			
		||||
 | 
			
		||||
      "Contribution" shall mean any work of authorship, including
 | 
			
		||||
      the original version of the Work and any modifications or additions
 | 
			
		||||
      to that Work or Derivative Works thereof, that is intentionally
 | 
			
		||||
      submitted to Licensor for inclusion in the Work by the copyright owner
 | 
			
		||||
      or by an individual or Legal Entity authorized to submit on behalf of
 | 
			
		||||
      the copyright owner. For the purposes of this definition, "submitted"
 | 
			
		||||
      means any form of electronic, verbal, or written communication sent
 | 
			
		||||
      to the Licensor or its representatives, including but not limited to
 | 
			
		||||
      communication on electronic mailing lists, source code control systems,
 | 
			
		||||
      and issue tracking systems that are managed by, or on behalf of, the
 | 
			
		||||
      Licensor for the purpose of discussing and improving the Work, but
 | 
			
		||||
      excluding communication that is conspicuously marked or otherwise
 | 
			
		||||
      designated in writing by the copyright owner as "Not a Contribution."
 | 
			
		||||
 | 
			
		||||
      "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
			
		||||
      on behalf of whom a Contribution has been received by Licensor and
 | 
			
		||||
      subsequently incorporated within the Work.
 | 
			
		||||
 | 
			
		||||
   2. Grant of Copyright License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      copyright license to reproduce, prepare Derivative Works of,
 | 
			
		||||
      publicly display, publicly perform, sublicense, and distribute the
 | 
			
		||||
      Work and such Derivative Works in Source or Object form.
 | 
			
		||||
 | 
			
		||||
   3. Grant of Patent License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      (except as stated in this section) patent license to make, have made,
 | 
			
		||||
      use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
			
		||||
      where such license applies only to those patent claims licensable
 | 
			
		||||
      by such Contributor that are necessarily infringed by their
 | 
			
		||||
      Contribution(s) alone or by combination of their Contribution(s)
 | 
			
		||||
      with the Work to which such Contribution(s) was submitted. If You
 | 
			
		||||
      institute patent litigation against any entity (including a
 | 
			
		||||
      cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
			
		||||
      or a Contribution incorporated within the Work constitutes direct
 | 
			
		||||
      or contributory patent infringement, then any patent licenses
 | 
			
		||||
      granted to You under this License for that Work shall terminate
 | 
			
		||||
      as of the date such litigation is filed.
 | 
			
		||||
 | 
			
		||||
   4. Redistribution. You may reproduce and distribute copies of the
 | 
			
		||||
      Work or Derivative Works thereof in any medium, with or without
 | 
			
		||||
      modifications, and in Source or Object form, provided that You
 | 
			
		||||
      meet the following conditions:
 | 
			
		||||
 | 
			
		||||
      (a) You must give any other recipients of the Work or
 | 
			
		||||
          Derivative Works a copy of this License; and
 | 
			
		||||
 | 
			
		||||
      (b) You must cause any modified files to carry prominent notices
 | 
			
		||||
          stating that You changed the files; and
 | 
			
		||||
 | 
			
		||||
      (c) You must retain, in the Source form of any Derivative Works
 | 
			
		||||
          that You distribute, all copyright, patent, trademark, and
 | 
			
		||||
          attribution notices from the Source form of the Work,
 | 
			
		||||
          excluding those notices that do not pertain to any part of
 | 
			
		||||
          the Derivative Works; and
 | 
			
		||||
 | 
			
		||||
      (d) If the Work includes a "NOTICE" text file as part of its
 | 
			
		||||
          distribution, then any Derivative Works that You distribute must
 | 
			
		||||
          include a readable copy of the attribution notices contained
 | 
			
		||||
          within such NOTICE file, excluding those notices that do not
 | 
			
		||||
          pertain to any part of the Derivative Works, in at least one
 | 
			
		||||
          of the following places: within a NOTICE text file distributed
 | 
			
		||||
          as part of the Derivative Works; within the Source form or
 | 
			
		||||
          documentation, if provided along with the Derivative Works; or,
 | 
			
		||||
          within a display generated by the Derivative Works, if and
 | 
			
		||||
          wherever such third-party notices normally appear. The contents
 | 
			
		||||
          of the NOTICE file are for informational purposes only and
 | 
			
		||||
          do not modify the License. You may add Your own attribution
 | 
			
		||||
          notices within Derivative Works that You distribute, alongside
 | 
			
		||||
          or as an addendum to the NOTICE text from the Work, provided
 | 
			
		||||
          that such additional attribution notices cannot be construed
 | 
			
		||||
          as modifying the License.
 | 
			
		||||
 | 
			
		||||
      You may add Your own copyright statement to Your modifications and
 | 
			
		||||
      may provide additional or different license terms and conditions
 | 
			
		||||
      for use, reproduction, or distribution of Your modifications, or
 | 
			
		||||
      for any such Derivative Works as a whole, provided Your use,
 | 
			
		||||
      reproduction, and distribution of the Work otherwise complies with
 | 
			
		||||
      the conditions stated in this License.
 | 
			
		||||
 | 
			
		||||
   5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
			
		||||
      any Contribution intentionally submitted for inclusion in the Work
 | 
			
		||||
      by You to the Licensor shall be under the terms and conditions of
 | 
			
		||||
      this License, without any additional terms or conditions.
 | 
			
		||||
      Notwithstanding the above, nothing herein shall supersede or modify
 | 
			
		||||
      the terms of any separate license agreement you may have executed
 | 
			
		||||
      with Licensor regarding such Contributions.
 | 
			
		||||
 | 
			
		||||
   6. Trademarks. This License does not grant permission to use the trade
 | 
			
		||||
      names, trademarks, service marks, or product names of the Licensor,
 | 
			
		||||
      except as required for reasonable and customary use in describing the
 | 
			
		||||
      origin of the Work and reproducing the content of the NOTICE file.
 | 
			
		||||
 | 
			
		||||
   7. Disclaimer of Warranty. Unless required by applicable law or
 | 
			
		||||
      agreed to in writing, Licensor provides the Work (and each
 | 
			
		||||
      Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
			
		||||
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
			
		||||
      implied, including, without limitation, any warranties or conditions
 | 
			
		||||
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
			
		||||
      PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
			
		||||
      appropriateness of using or redistributing the Work and assume any
 | 
			
		||||
      risks associated with Your exercise of permissions under this License.
 | 
			
		||||
 | 
			
		||||
   8. Limitation of Liability. In no event and under no legal theory,
 | 
			
		||||
      whether in tort (including negligence), contract, or otherwise,
 | 
			
		||||
      unless required by applicable law (such as deliberate and grossly
 | 
			
		||||
      negligent acts) or agreed to in writing, shall any Contributor be
 | 
			
		||||
      liable to You for damages, including any direct, indirect, special,
 | 
			
		||||
      incidental, or consequential damages of any character arising as a
 | 
			
		||||
      result of this License or out of the use or inability to use the
 | 
			
		||||
      Work (including but not limited to damages for loss of goodwill,
 | 
			
		||||
      work stoppage, computer failure or malfunction, or any and all
 | 
			
		||||
      other commercial damages or losses), even if such Contributor
 | 
			
		||||
      has been advised of the possibility of such damages.
 | 
			
		||||
 | 
			
		||||
   9. Accepting Warranty or Additional Liability. While redistributing
 | 
			
		||||
      the Work or Derivative Works thereof, You may choose to offer,
 | 
			
		||||
      and charge a fee for, acceptance of support, warranty, indemnity,
 | 
			
		||||
      or other liability obligations and/or rights consistent with this
 | 
			
		||||
      License. However, in accepting such obligations, You may act only
 | 
			
		||||
      on Your own behalf and on Your sole responsibility, not on behalf
 | 
			
		||||
      of any other Contributor, and only if You agree to indemnify,
 | 
			
		||||
      defend, and hold each Contributor harmless for any liability
 | 
			
		||||
      incurred by, or claims asserted against, such Contributor by reason
 | 
			
		||||
      of your accepting any such warranty or additional liability.
 | 
			
		||||
 | 
			
		||||
   END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
   APPENDIX: How to apply the Apache License to your work.
 | 
			
		||||
 | 
			
		||||
      To apply the Apache License to your work, attach the following
 | 
			
		||||
      boilerplate notice, with the fields enclosed by brackets "[]"
 | 
			
		||||
      replaced with your own identifying information. (Don't include
 | 
			
		||||
      the brackets!)  The text should be enclosed in the appropriate
 | 
			
		||||
      comment syntax for the file format. We also recommend that a
 | 
			
		||||
      file or class name and description of purpose be included on the
 | 
			
		||||
      same "printed page" as the copyright notice for easier
 | 
			
		||||
      identification within third-party archives.
 | 
			
		||||
 | 
			
		||||
   Copyright [yyyy] [name of copyright owner]
 | 
			
		||||
 | 
			
		||||
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
   you may not use this file except in compliance with the License.
 | 
			
		||||
   You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
       http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
   Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
   See the License for the specific language governing permissions and
 | 
			
		||||
   limitations under the License.
 | 
			
		||||
							
								
								
									
										28
									
								
								server/node_modules/monk/node_modules/mongodb/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										28
									
								
								server/node_modules/monk/node_modules/mongodb/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
NODE = node
 | 
			
		||||
NPM = npm
 | 
			
		||||
NODEUNIT = node_modules/nodeunit/bin/nodeunit
 | 
			
		||||
DOX = node_modules/dox/bin/dox
 | 
			
		||||
name = all
 | 
			
		||||
 | 
			
		||||
total: build_native
 | 
			
		||||
 | 
			
		||||
test_functional:
 | 
			
		||||
	node test/runner.js -t functional
 | 
			
		||||
 | 
			
		||||
test_ssl:
 | 
			
		||||
	node test/runner.js -t ssl	
 | 
			
		||||
 | 
			
		||||
test_replicaset:
 | 
			
		||||
	node test/runner.js -t replicaset
 | 
			
		||||
 | 
			
		||||
test_sharded:
 | 
			
		||||
	node test/runner.js -t sharded
 | 
			
		||||
 | 
			
		||||
test_auth:
 | 
			
		||||
	node test/runner.js -t auth
 | 
			
		||||
 | 
			
		||||
generate_docs:
 | 
			
		||||
	$(NODE) dev/tools/build-docs.js
 | 
			
		||||
	make --directory=./docs/sphinx-docs --file=Makefile html
 | 
			
		||||
 | 
			
		||||
.PHONY: total
 | 
			
		||||
							
								
								
									
										418
									
								
								server/node_modules/monk/node_modules/mongodb/Readme.md
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										418
									
								
								server/node_modules/monk/node_modules/mongodb/Readme.md
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,418 @@
 | 
			
		||||
## MongoDB Node.JS Driver
 | 
			
		||||
 
 | 
			
		||||
| what          | where                                          |
 | 
			
		||||
|---------------|------------------------------------------------|
 | 
			
		||||
| documentation | http://mongodb.github.io/node-mongodb-native/  |
 | 
			
		||||
| apidoc        | http://mongodb.github.io/node-mongodb-native/  |
 | 
			
		||||
| source        | https://github.com/mongodb/node-mongodb-native |
 | 
			
		||||
| mongodb       | http://www.mongodb.org/                        |
 | 
			
		||||
 | 
			
		||||
### Blogs of Engineers involved in the driver
 | 
			
		||||
- Christian Kvalheim [@christkv](https://twitter.com/christkv) <http://christiankvalheim.com>
 | 
			
		||||
- Valeri Karpov [@code_barbarian](https://twitter.com/code_barbarian) <http://thecodebarbarian.wordpress.com/>
 | 
			
		||||
 | 
			
		||||
### Bugs / Feature Requests
 | 
			
		||||
 | 
			
		||||
Think you’ve found a bug? Want to see a new feature in node-mongodb-native? Please open a
 | 
			
		||||
case in our issue management tool, JIRA:
 | 
			
		||||
 | 
			
		||||
- Create an account and login <https://jira.mongodb.org>.
 | 
			
		||||
- Navigate to the NODE project <https://jira.mongodb.org/browse/NODE>.
 | 
			
		||||
- Click **Create Issue** - Please provide as much information as possible about the issue type and how to reproduce it.
 | 
			
		||||
 | 
			
		||||
Bug reports in JIRA for all driver projects (i.e. NODE, PYTHON, CSHARP, JAVA) and the
 | 
			
		||||
Core Server (i.e. SERVER) project are **public**.
 | 
			
		||||
 | 
			
		||||
### Questions and Bug Reports
 | 
			
		||||
 | 
			
		||||
 * mailing list: https://groups.google.com/forum/#!forum/node-mongodb-native
 | 
			
		||||
 * jira: http://jira.mongodb.org/
 | 
			
		||||
 | 
			
		||||
### Change Log
 | 
			
		||||
 | 
			
		||||
http://jira.mongodb.org/browse/NODE
 | 
			
		||||
 | 
			
		||||
## Install
 | 
			
		||||
 | 
			
		||||
To install the most recent release from npm, run:
 | 
			
		||||
 | 
			
		||||
    npm install mongodb
 | 
			
		||||
 | 
			
		||||
That may give you a warning telling you that bugs['web'] should be bugs['url'], it would be safe to ignore it (this has been fixed in the development version)
 | 
			
		||||
 | 
			
		||||
To install the latest from the repository, run::
 | 
			
		||||
 | 
			
		||||
    npm install path/to/node-mongodb-native
 | 
			
		||||
 | 
			
		||||
## Live Examples
 | 
			
		||||
<a href="https://runnable.com/node-mongodb-native" target="_blank"><img src="https://runnable.com/external/styles/assets/runnablebtn.png" style="width:67px;height:25px;"></a>
 | 
			
		||||
 | 
			
		||||
## Introduction
 | 
			
		||||
 | 
			
		||||
This is a node.js driver for MongoDB. It's a port (or close to a port) of the library for ruby at http://github.com/mongodb/mongo-ruby-driver/.
 | 
			
		||||
 | 
			
		||||
A simple example of inserting a document.
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
  var MongoClient = require('mongodb').MongoClient
 | 
			
		||||
    , format = require('util').format;
 | 
			
		||||
 | 
			
		||||
  MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) {
 | 
			
		||||
    if(err) throw err;
 | 
			
		||||
 | 
			
		||||
    var collection = db.collection('test_insert');
 | 
			
		||||
    collection.insert({a:2}, function(err, docs) {
 | 
			
		||||
      
 | 
			
		||||
      collection.count(function(err, count) {
 | 
			
		||||
        console.log(format("count = %s", count));
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      // Locate all the entries using find
 | 
			
		||||
      collection.find().toArray(function(err, results) {
 | 
			
		||||
        console.dir(results);
 | 
			
		||||
        // Let's close the db
 | 
			
		||||
        db.close();
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  })
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Data types
 | 
			
		||||
 | 
			
		||||
To store and retrieve the non-JSON MongoDb primitives ([ObjectID](http://www.mongodb.org/display/DOCS/Object+IDs), Long, Binary, [Timestamp](http://www.mongodb.org/display/DOCS/Timestamp+data+type), [DBRef](http://www.mongodb.org/display/DOCS/Database+References#DatabaseReferences-DBRef), Code).
 | 
			
		||||
 | 
			
		||||
In particular, every document has a unique `_id` which can be almost any type, and by default a 12-byte ObjectID is created. ObjectIDs can be represented as 24-digit hexadecimal strings, but you must convert the string back into an ObjectID before you can use it in the database. For example:
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
  // Get the objectID type
 | 
			
		||||
  var ObjectID = require('mongodb').ObjectID;
 | 
			
		||||
 | 
			
		||||
  var idString = '4e4e1638c85e808431000003';
 | 
			
		||||
  collection.findOne({_id: new ObjectID(idString)}, console.log)  // ok
 | 
			
		||||
  collection.findOne({_id: idString}, console.log)  // wrong! callback gets undefined
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Here are the constructors the non-Javascript BSON primitive types:
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
  // Fetch the library
 | 
			
		||||
  var mongo = require('mongodb');
 | 
			
		||||
  // Create new instances of BSON types
 | 
			
		||||
  new mongo.Long(numberString)
 | 
			
		||||
  new mongo.ObjectID(hexString)
 | 
			
		||||
  new mongo.Timestamp()  // the actual unique number is generated on insert.
 | 
			
		||||
  new mongo.DBRef(collectionName, id, dbName)
 | 
			
		||||
  new mongo.Binary(buffer)  // takes a string or Buffer
 | 
			
		||||
  new mongo.Code(code, [context])
 | 
			
		||||
  new mongo.Symbol(string)
 | 
			
		||||
  new mongo.MinKey()
 | 
			
		||||
  new mongo.MaxKey()
 | 
			
		||||
  new mongo.Double(number)	// Force double storage
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### The C/C++ bson parser/serializer
 | 
			
		||||
 | 
			
		||||
If you are running a version of this library has the C/C++ parser compiled, to enable the driver to use the C/C++ bson parser pass it the option native_parser:true like below
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
  // using native_parser:
 | 
			
		||||
  MongoClient.connect('mongodb://127.0.0.1:27017/test'
 | 
			
		||||
    , {db: {native_parser: true}}, function(err, db) {})
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The C++ parser uses the js objects both for serialization and deserialization.
 | 
			
		||||
 | 
			
		||||
## GitHub information
 | 
			
		||||
 | 
			
		||||
The source code is available at http://github.com/mongodb/node-mongodb-native.
 | 
			
		||||
You can either clone the repository or download a tarball of the latest release.
 | 
			
		||||
 | 
			
		||||
Once you have the source you can test the driver by running
 | 
			
		||||
 | 
			
		||||
    $ node test/runner.js -t functional
 | 
			
		||||
 | 
			
		||||
in the main directory. You will need to have a mongo instance running on localhost for the integration tests to pass.
 | 
			
		||||
 | 
			
		||||
## Examples
 | 
			
		||||
 | 
			
		||||
For examples look in the examples/ directory. You can execute the examples using node.
 | 
			
		||||
 | 
			
		||||
    $ cd examples
 | 
			
		||||
    $ node queries.js
 | 
			
		||||
 | 
			
		||||
## GridStore
 | 
			
		||||
 | 
			
		||||
The GridStore class allows for storage of binary files in mongoDB using the mongoDB defined files and chunks collection definition.
 | 
			
		||||
 | 
			
		||||
For more information have a look at [Gridstore](https://github.com/mongodb/node-mongodb-native/blob/master/docs/gridfs.md)
 | 
			
		||||
 | 
			
		||||
## Replicasets
 | 
			
		||||
 | 
			
		||||
For more information about how to connect to a replicaset have a look at the extensive documentation [Documentation](http://mongodb.github.com/node-mongodb-native/)
 | 
			
		||||
 | 
			
		||||
### Primary Key Factories
 | 
			
		||||
 | 
			
		||||
Defining your own primary key factory allows you to generate your own series of id's
 | 
			
		||||
(this could f.ex be to use something like ISBN numbers). The generated the id needs to be a 12 byte long "string".
 | 
			
		||||
 | 
			
		||||
Simple example below
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
  var MongoClient = require('mongodb').MongoClient
 | 
			
		||||
    , format = require('util').format;    
 | 
			
		||||
 | 
			
		||||
  // Custom factory (need to provide a 12 byte array);
 | 
			
		||||
  CustomPKFactory = function() {}
 | 
			
		||||
  CustomPKFactory.prototype = new Object();
 | 
			
		||||
  CustomPKFactory.createPk = function() {
 | 
			
		||||
    return new ObjectID("aaaaaaaaaaaa");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  MongoClient.connect('mongodb://127.0.0.1:27017/test', {'pkFactory':CustomPKFactory}, function(err, db) {
 | 
			
		||||
    if(err) throw err;
 | 
			
		||||
 | 
			
		||||
    db.dropDatabase(function(err, done) {
 | 
			
		||||
      
 | 
			
		||||
      db.createCollection('test_custom_key', function(err, collection) {
 | 
			
		||||
        
 | 
			
		||||
        collection.insert({'a':1}, function(err, docs) {
 | 
			
		||||
          
 | 
			
		||||
          collection.find({'_id':new ObjectID("aaaaaaaaaaaa")}).toArray(function(err, items) {
 | 
			
		||||
            console.dir(items);
 | 
			
		||||
            // Let's close the db
 | 
			
		||||
            db.close();
 | 
			
		||||
          });
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Documentation
 | 
			
		||||
 | 
			
		||||
If this document doesn't answer your questions, see the source of
 | 
			
		||||
[Collection](https://github.com/mongodb/node-mongodb-native/blob/master/lib/mongodb/collection.js)
 | 
			
		||||
or [Cursor](https://github.com/mongodb/node-mongodb-native/blob/master/lib/mongodb/cursor.js),
 | 
			
		||||
or the documentation at MongoDB for query and update formats.
 | 
			
		||||
 | 
			
		||||
### Find
 | 
			
		||||
 | 
			
		||||
The find method is actually a factory method to create
 | 
			
		||||
Cursor objects. A Cursor lazily uses the connection the first time
 | 
			
		||||
you call `nextObject`, `each`, or `toArray`.
 | 
			
		||||
 | 
			
		||||
The basic operation on a cursor is the `nextObject` method
 | 
			
		||||
that fetches the next matching document from the database. The convenience
 | 
			
		||||
methods `each` and `toArray` call `nextObject` until the cursor is exhausted.
 | 
			
		||||
 | 
			
		||||
Signatures:
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
  var cursor = collection.find(query, [fields], options);
 | 
			
		||||
  cursor.sort(fields).limit(n).skip(m).
 | 
			
		||||
 | 
			
		||||
  cursor.nextObject(function(err, doc) {});
 | 
			
		||||
  cursor.each(function(err, doc) {});
 | 
			
		||||
  cursor.toArray(function(err, docs) {});
 | 
			
		||||
 | 
			
		||||
  cursor.rewind()  // reset the cursor to its initial state.
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Useful chainable methods of cursor. These can optionally be options of `find` instead of method calls:
 | 
			
		||||
 | 
			
		||||
  * `.limit(n).skip(m)` to control paging.
 | 
			
		||||
  * `.sort(fields)` Order by the given fields. There are several equivalent syntaxes:
 | 
			
		||||
  * `.sort({field1: -1, field2: 1})` descending by field1, then ascending by field2.
 | 
			
		||||
  * `.sort([['field1', 'desc'], ['field2', 'asc']])` same as above
 | 
			
		||||
  * `.sort([['field1', 'desc'], 'field2'])` same as above
 | 
			
		||||
  * `.sort('field1')` ascending by field1
 | 
			
		||||
 | 
			
		||||
Other options of `find`:
 | 
			
		||||
 | 
			
		||||
* `fields` the fields to fetch (to avoid transferring the entire document)
 | 
			
		||||
* `tailable` if true, makes the cursor [tailable](http://www.mongodb.org/display/DOCS/Tailable+Cursors).
 | 
			
		||||
* `batchSize` The number of the subset of results to request the database
 | 
			
		||||
to return for every request. This should initially be greater than 1 otherwise
 | 
			
		||||
the database will automatically close the cursor. The batch size can be set to 1
 | 
			
		||||
with `batchSize(n, function(err){})` after performing the initial query to the database.
 | 
			
		||||
* `hint` See [Optimization: hint](http://www.mongodb.org/display/DOCS/Optimization#Optimization-Hint).
 | 
			
		||||
* `explain` turns this into an explain query. You can also call
 | 
			
		||||
`explain()` on any cursor to fetch the explanation.
 | 
			
		||||
* `snapshot` prevents documents that are updated while the query is active
 | 
			
		||||
from being returned multiple times. See more
 | 
			
		||||
[details about query snapshots](http://www.mongodb.org/display/DOCS/How+to+do+Snapshotted+Queries+in+the+Mongo+Database).
 | 
			
		||||
* `timeout` if false, asks MongoDb not to time out this cursor after an
 | 
			
		||||
inactivity period.
 | 
			
		||||
 | 
			
		||||
For information on how to create queries, see the
 | 
			
		||||
[MongoDB section on querying](http://www.mongodb.org/display/DOCS/Querying).
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
  var MongoClient = require('mongodb').MongoClient
 | 
			
		||||
    , format = require('util').format;    
 | 
			
		||||
 | 
			
		||||
  MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) {
 | 
			
		||||
    if(err) throw err;
 | 
			
		||||
 | 
			
		||||
    var collection = db
 | 
			
		||||
      .collection('test')
 | 
			
		||||
      .find({})
 | 
			
		||||
      .limit(10)
 | 
			
		||||
      .toArray(function(err, docs) {
 | 
			
		||||
        console.dir(docs);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Insert
 | 
			
		||||
 | 
			
		||||
Signature:
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
  collection.insert(docs, options, [callback]);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
where `docs` can be a single document or an array of documents.
 | 
			
		||||
 | 
			
		||||
Useful options:
 | 
			
		||||
 | 
			
		||||
* `w:1` Should always set if you have a callback.
 | 
			
		||||
 | 
			
		||||
See also: [MongoDB docs for insert](http://www.mongodb.org/display/DOCS/Inserting).
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
  var MongoClient = require('mongodb').MongoClient
 | 
			
		||||
    , format = require('util').format;    
 | 
			
		||||
 | 
			
		||||
  MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) {
 | 
			
		||||
    if(err) throw err;
 | 
			
		||||
    
 | 
			
		||||
    db.collection('test').insert({hello: 'world'}, {w:1}, function(err, objects) {
 | 
			
		||||
      if (err) console.warn(err.message);
 | 
			
		||||
      if (err && err.message.indexOf('E11000 ') !== -1) {
 | 
			
		||||
        // this _id was already inserted in the database
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Note that there's no reason to pass a callback to the insert or update commands
 | 
			
		||||
unless you use the `w:1` option. If you don't specify `w:1`, then
 | 
			
		||||
your callback will be called immediately.
 | 
			
		||||
 | 
			
		||||
### Update: update and insert (upsert)
 | 
			
		||||
 | 
			
		||||
The update operation will update the first document that matches your query
 | 
			
		||||
(or all documents that match if you use `multi:true`).
 | 
			
		||||
If `w:1`, `upsert` is not set, and no documents match, your callback will return 0 documents updated.
 | 
			
		||||
 | 
			
		||||
See the [MongoDB docs](http://www.mongodb.org/display/DOCS/Updating) for
 | 
			
		||||
the modifier (`$inc`, `$set`, `$push`, etc.) formats.
 | 
			
		||||
 | 
			
		||||
Signature:
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
  collection.update(criteria, objNew, options, [callback]);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Useful options:
 | 
			
		||||
 | 
			
		||||
* `w:1` Should always set if you have a callback.
 | 
			
		||||
* `multi:true` If set, all matching documents are updated, not just the first.
 | 
			
		||||
* `upsert:true` Atomically inserts the document if no documents matched.
 | 
			
		||||
 | 
			
		||||
Example for `update`:
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
  var MongoClient = require('mongodb').MongoClient
 | 
			
		||||
    , format = require('util').format;    
 | 
			
		||||
 | 
			
		||||
  MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) {
 | 
			
		||||
    if(err) throw err;
 | 
			
		||||
 | 
			
		||||
    db.collection('test').update({hi: 'here'}, {$set: {hi: 'there'}}, {w:1}, function(err) {
 | 
			
		||||
      if (err) console.warn(err.message);
 | 
			
		||||
      else console.log('successfully updated');
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Find and modify
 | 
			
		||||
 | 
			
		||||
`findAndModify` is like `update`, but it also gives the updated document to
 | 
			
		||||
your callback. But there are a few key differences between findAndModify and
 | 
			
		||||
update:
 | 
			
		||||
 | 
			
		||||
  1. The signatures differ.
 | 
			
		||||
  2. You can only findAndModify a single item, not multiple items.
 | 
			
		||||
 | 
			
		||||
Signature:
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
    collection.findAndModify(query, sort, update, options, callback)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The sort parameter is used to specify which object to operate on, if more than
 | 
			
		||||
one document matches. It takes the same format as the cursor sort (see
 | 
			
		||||
Connection.find above).
 | 
			
		||||
 | 
			
		||||
See the
 | 
			
		||||
[MongoDB docs for findAndModify](http://www.mongodb.org/display/DOCS/findAndModify+Command)
 | 
			
		||||
for more details.
 | 
			
		||||
 | 
			
		||||
Useful options:
 | 
			
		||||
 | 
			
		||||
* `remove:true` set to a true to remove the object before returning
 | 
			
		||||
* `new:true` set to true if you want to return the modified object rather than the original. Ignored for remove.
 | 
			
		||||
* `upsert:true` Atomically inserts the document if no documents matched.
 | 
			
		||||
 | 
			
		||||
Example for `findAndModify`:
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
  var MongoClient = require('mongodb').MongoClient
 | 
			
		||||
    , format = require('util').format;    
 | 
			
		||||
 | 
			
		||||
  MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) {
 | 
			
		||||
    if(err) throw err;
 | 
			
		||||
    db.collection('test').findAndModify({hello: 'world'}, [['_id','asc']], {$set: {hi: 'there'}}, {}, function(err, object) {
 | 
			
		||||
      if (err) console.warn(err.message);
 | 
			
		||||
      else console.dir(object);  // undefined if no matching object exists.
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Save
 | 
			
		||||
 | 
			
		||||
The `save` method is a shorthand for upsert if the document contains an
 | 
			
		||||
`_id`, or an insert if there is no `_id`.
 | 
			
		||||
 | 
			
		||||
## Release Notes
 | 
			
		||||
 | 
			
		||||
See HISTORY
 | 
			
		||||
 | 
			
		||||
## Credits
 | 
			
		||||
 | 
			
		||||
1. [10gen](http://github.com/mongodb/mongo-ruby-driver/)
 | 
			
		||||
2. [Google Closure Library](http://code.google.com/closure/library/)
 | 
			
		||||
3. [Jonas Raoni Soares Silva](http://jsfromhell.com/classes/binary-parser)
 | 
			
		||||
 | 
			
		||||
## Contributors
 | 
			
		||||
 | 
			
		||||
Aaron Heckmann, Christoph Pojer, Pau Ramon Revilla, Nathan White, Emmerman, Seth LaForge, Boris Filipov, Stefan Schärmeli, Tedde Lundgren, renctan, Sergey Ukustov, Ciaran Jessup, kuno, srimonti, Erik Abele, Pratik Daga, Slobodan Utvic, Kristina Chodorow, Yonathan Randolph, Brian Noguchi, Sam Epstein, James Harrison Fisher, Vladimir Dronnikov, Ben Hockey, Henrik Johansson, Simon Weare, Alex Gorbatchev, Shimon Doodkin, Kyle Mueller, Eran Hammer-Lahav, Marcin Ciszak, François de Metz, Vinay Pulim, nstielau, Adam Wiggins, entrinzikyl, Jeremy Selier, Ian Millington, Public Keating, andrewjstone, Christopher Stott, Corey Jewett, brettkiefer, Rob Holland, Senmiao Liu, heroic, gitfy
 | 
			
		||||
 | 
			
		||||
## License
 | 
			
		||||
 | 
			
		||||
 Copyright 2009 - 2013 MongoDb Inc.
 | 
			
		||||
 | 
			
		||||
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
   you may not use this file except in compliance with the License.
 | 
			
		||||
   You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
       http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
   Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
   See the License for the specific language governing permissions and
 | 
			
		||||
   limitations under the License.
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								server/node_modules/monk/node_modules/mongodb/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										1
									
								
								server/node_modules/monk/node_modules/mongodb/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
module.exports = require('./lib/mongodb');
 | 
			
		||||
							
								
								
									
										340
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/admin.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										340
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/admin.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,340 @@
 | 
			
		||||
/*!
 | 
			
		||||
 * Module dependencies.
 | 
			
		||||
 */
 | 
			
		||||
var Collection = require('./collection').Collection,
 | 
			
		||||
    Cursor = require('./cursor').Cursor,
 | 
			
		||||
    DbCommand = require('./commands/db_command').DbCommand,
 | 
			
		||||
    utils = require('./utils');
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Allows the user to access the admin functionality of MongoDB
 | 
			
		||||
 *
 | 
			
		||||
 * @class Represents the Admin methods of MongoDB.
 | 
			
		||||
 * @param {Object} db Current db instance we wish to perform Admin operations on.
 | 
			
		||||
 * @return {Function} Constructor for Admin type.
 | 
			
		||||
 */
 | 
			
		||||
function Admin(db) {
 | 
			
		||||
  if(!(this instanceof Admin)) return new Admin(db);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Retrieve the server information for the current
 | 
			
		||||
   * instance of the db client
 | 
			
		||||
   *
 | 
			
		||||
   * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from buildInfo or null if an error occured.
 | 
			
		||||
   * @return {null} Returns no result
 | 
			
		||||
   * @api public
 | 
			
		||||
   */
 | 
			
		||||
  this.buildInfo = function(callback) {
 | 
			
		||||
    this.serverInfo(callback);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Retrieve the server information for the current
 | 
			
		||||
   * instance of the db client
 | 
			
		||||
   *
 | 
			
		||||
   * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from serverInfo or null if an error occured.
 | 
			
		||||
   * @return {null} Returns no result
 | 
			
		||||
   * @api private
 | 
			
		||||
   */
 | 
			
		||||
  this.serverInfo = function(callback) {
 | 
			
		||||
    db.executeDbAdminCommand({buildinfo:1}, function(err, doc) {
 | 
			
		||||
      if(err != null) return callback(err, null);
 | 
			
		||||
      return callback(null, doc.documents[0]);
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Retrieve this db's server status.
 | 
			
		||||
   *
 | 
			
		||||
   * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from serverStatus or null if an error occured.
 | 
			
		||||
   * @return {null}
 | 
			
		||||
   * @api public
 | 
			
		||||
   */
 | 
			
		||||
  this.serverStatus = function(callback) {
 | 
			
		||||
    var self = this;
 | 
			
		||||
 | 
			
		||||
    db.executeDbAdminCommand({serverStatus: 1}, function(err, doc) {
 | 
			
		||||
      if(err == null && doc.documents[0].ok === 1) {
 | 
			
		||||
        callback(null, doc.documents[0]);
 | 
			
		||||
      } else {
 | 
			
		||||
        if(err) return callback(err, false);
 | 
			
		||||
        return callback(utils.toError(doc.documents[0]), false);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Retrieve the current profiling Level for MongoDB
 | 
			
		||||
   *
 | 
			
		||||
   * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from profilingLevel or null if an error occured.
 | 
			
		||||
   * @return {null} Returns no result
 | 
			
		||||
   * @api public
 | 
			
		||||
   */
 | 
			
		||||
  this.profilingLevel = function(callback) {
 | 
			
		||||
    var self = this;
 | 
			
		||||
 | 
			
		||||
    db.executeDbAdminCommand({profile:-1}, function(err, doc) {
 | 
			
		||||
      doc = doc.documents[0];
 | 
			
		||||
 | 
			
		||||
      if(err == null && doc.ok === 1) {
 | 
			
		||||
        var was = doc.was;
 | 
			
		||||
        if(was == 0) return callback(null, "off");
 | 
			
		||||
        if(was == 1) return callback(null, "slow_only");
 | 
			
		||||
        if(was == 2) return callback(null, "all");
 | 
			
		||||
          return callback(new Error("Error: illegal profiling level value " + was), null);
 | 
			
		||||
      } else {
 | 
			
		||||
        err != null ? callback(err, null) : callback(new Error("Error with profile command"), null);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Ping the MongoDB server and retrieve results
 | 
			
		||||
   *
 | 
			
		||||
   * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from ping or null if an error occured.
 | 
			
		||||
   * @return {null} Returns no result
 | 
			
		||||
   * @api public
 | 
			
		||||
   */
 | 
			
		||||
  this.ping = function(options, callback) {
 | 
			
		||||
    // Unpack calls
 | 
			
		||||
    var args = Array.prototype.slice.call(arguments, 0);
 | 
			
		||||
    db.executeDbAdminCommand({ping: 1}, args.pop());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Authenticate against MongoDB
 | 
			
		||||
   *
 | 
			
		||||
   * @param {String} username The user name for the authentication.
 | 
			
		||||
   * @param {String} password The password for the authentication.
 | 
			
		||||
   * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from authenticate or null if an error occured.
 | 
			
		||||
   * @return {null} Returns no result
 | 
			
		||||
   * @api public
 | 
			
		||||
   */
 | 
			
		||||
  this.authenticate = function(username, password, callback) {
 | 
			
		||||
    db.authenticate(username, password, {authdb: 'admin'}, function(err, doc) {
 | 
			
		||||
      return callback(err, doc);
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Logout current authenticated user
 | 
			
		||||
   *
 | 
			
		||||
   * @param {Object} [options] Optional parameters to the command.
 | 
			
		||||
   * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from logout or null if an error occured.
 | 
			
		||||
   * @return {null} Returns no result
 | 
			
		||||
   * @api public
 | 
			
		||||
   */
 | 
			
		||||
  this.logout = function(callback) {
 | 
			
		||||
    db.logout({authdb: 'admin'},  function(err, doc) {
 | 
			
		||||
      return callback(err, doc);
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Add a user to the MongoDB server, if the user exists it will
 | 
			
		||||
   * overwrite the current password
 | 
			
		||||
   *
 | 
			
		||||
   * Options
 | 
			
		||||
   *  - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write
 | 
			
		||||
   *  - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option)
 | 
			
		||||
   *  - **fsync**, (Boolean, default:false) write waits for fsync before returning, from MongoDB 2.6 on, fsync cannot be combined with journal
 | 
			
		||||
   *  - **j**, (Boolean, default:false) write waits for journal sync before returning
 | 
			
		||||
   *
 | 
			
		||||
   * @param {String} username The user name for the authentication.
 | 
			
		||||
   * @param {String} password The password for the authentication.
 | 
			
		||||
   * @param {Object} [options] additional options during update.
 | 
			
		||||
   * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from addUser or null if an error occured.
 | 
			
		||||
   * @return {null} Returns no result
 | 
			
		||||
   * @api public
 | 
			
		||||
   */
 | 
			
		||||
  this.addUser = function(username, password, options, callback) {
 | 
			
		||||
    var args = Array.prototype.slice.call(arguments, 2);
 | 
			
		||||
    callback = args.pop();
 | 
			
		||||
    options = args.length ? args.shift() : {};
 | 
			
		||||
    // Set the db name to admin
 | 
			
		||||
    options.dbName = 'admin';
 | 
			
		||||
    // Add user
 | 
			
		||||
    db.addUser(username, password, options, function(err, doc) {
 | 
			
		||||
      return callback(err, doc);
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
  /**
 | 
			
		||||
   * Remove a user from the MongoDB server
 | 
			
		||||
   *
 | 
			
		||||
   * Options
 | 
			
		||||
   *  - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write
 | 
			
		||||
   *  - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option)
 | 
			
		||||
   *  - **fsync**, (Boolean, default:false) write waits for fsync before returning, from MongoDB 2.6 on, fsync cannot be combined with journal
 | 
			
		||||
   *  - **j**, (Boolean, default:false) write waits for journal sync before returning
 | 
			
		||||
   *
 | 
			
		||||
   * @param {String} username The user name for the authentication.
 | 
			
		||||
   * @param {Object} [options] additional options during update.
 | 
			
		||||
   * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from removeUser or null if an error occured.
 | 
			
		||||
   * @return {null} Returns no result
 | 
			
		||||
   * @api public
 | 
			
		||||
   */
 | 
			
		||||
  this.removeUser = function(username, options, callback) {
 | 
			
		||||
    var self = this;
 | 
			
		||||
    var args = Array.prototype.slice.call(arguments, 1);
 | 
			
		||||
    callback = args.pop();
 | 
			
		||||
    options = args.length ? args.shift() : {};
 | 
			
		||||
    options.dbName = 'admin';
 | 
			
		||||
 | 
			
		||||
    db.removeUser(username, options, function(err, doc) {
 | 
			
		||||
      return callback(err, doc);
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Set the current profiling level of MongoDB
 | 
			
		||||
   *
 | 
			
		||||
   * @param {String} level The new profiling level (off, slow_only, all)
 | 
			
		||||
   * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from setProfilingLevel or null if an error occured.
 | 
			
		||||
   * @return {null} Returns no result
 | 
			
		||||
   * @api public
 | 
			
		||||
   */
 | 
			
		||||
  this.setProfilingLevel = function(level, callback) {
 | 
			
		||||
    var self = this;
 | 
			
		||||
    var command = {};
 | 
			
		||||
    var profile = 0;
 | 
			
		||||
 | 
			
		||||
    if(level == "off") {
 | 
			
		||||
      profile = 0;
 | 
			
		||||
    } else if(level == "slow_only") {
 | 
			
		||||
      profile = 1;
 | 
			
		||||
    } else if(level == "all") {
 | 
			
		||||
      profile = 2;
 | 
			
		||||
    } else {
 | 
			
		||||
      return callback(new Error("Error: illegal profiling level value " + level));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Set up the profile number
 | 
			
		||||
    command['profile'] = profile;
 | 
			
		||||
 | 
			
		||||
    db.executeDbAdminCommand(command, function(err, doc) {
 | 
			
		||||
      doc = doc.documents[0];
 | 
			
		||||
 | 
			
		||||
      if(err == null && doc.ok === 1)
 | 
			
		||||
        return callback(null, level);
 | 
			
		||||
      return err != null ? callback(err, null) : callback(new Error("Error with profile command"), null);
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Retrive the current profiling information for MongoDB
 | 
			
		||||
   *
 | 
			
		||||
   * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from profilingInfo or null if an error occured.
 | 
			
		||||
   * @return {null} Returns no result
 | 
			
		||||
   * @api public
 | 
			
		||||
   */
 | 
			
		||||
  this.profilingInfo = function(callback) {
 | 
			
		||||
    try {
 | 
			
		||||
      new Cursor(db, new Collection(db, DbCommand.SYSTEM_PROFILE_COLLECTION), {}, {}, {dbName: 'admin'}).toArray(function(err, items) {
 | 
			
		||||
          return callback(err, items);
 | 
			
		||||
      });
 | 
			
		||||
    } catch (err) {
 | 
			
		||||
      return callback(err, null);
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Execute a db command against the Admin database
 | 
			
		||||
   *
 | 
			
		||||
   * @param {Object} command A command object `{ping:1}`.
 | 
			
		||||
   * @param {Object} [options] Optional parameters to the command.
 | 
			
		||||
   * @param {Function} callback this will be called after executing this method. The command always return the whole result of the command as the second parameter.
 | 
			
		||||
   * @return {null} Returns no result
 | 
			
		||||
   * @api public
 | 
			
		||||
   */
 | 
			
		||||
  this.command = function(command, options, callback) {
 | 
			
		||||
    var self = this;
 | 
			
		||||
    var args = Array.prototype.slice.call(arguments, 1);
 | 
			
		||||
    callback = args.pop();
 | 
			
		||||
    options = args.length ? args.shift() : {};
 | 
			
		||||
 | 
			
		||||
    // Execute a command
 | 
			
		||||
    db.executeDbAdminCommand(command, options, function(err, doc) {
 | 
			
		||||
      // Ensure change before event loop executes
 | 
			
		||||
      return callback != null ? callback(err, doc) : null;
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Validate an existing collection
 | 
			
		||||
   *
 | 
			
		||||
   * @param {String} collectionName The name of the collection to validate.
 | 
			
		||||
   * @param {Object} [options] Optional parameters to the command.
 | 
			
		||||
   * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from validateCollection or null if an error occured.
 | 
			
		||||
   * @return {null} Returns no result
 | 
			
		||||
   * @api public
 | 
			
		||||
   */
 | 
			
		||||
  this.validateCollection = function(collectionName, options, callback) {
 | 
			
		||||
    var args = Array.prototype.slice.call(arguments, 1);
 | 
			
		||||
    callback = args.pop();
 | 
			
		||||
    options = args.length ? args.shift() : {};
 | 
			
		||||
 | 
			
		||||
    var self = this;
 | 
			
		||||
    var command = {validate: collectionName};
 | 
			
		||||
    var keys = Object.keys(options);
 | 
			
		||||
 | 
			
		||||
    // Decorate command with extra options
 | 
			
		||||
    for(var i = 0; i < keys.length; i++) {
 | 
			
		||||
      if(options.hasOwnProperty(keys[i])) {
 | 
			
		||||
        command[keys[i]] = options[keys[i]];
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    db.command(command, function(err, doc) {
 | 
			
		||||
      if(err != null) return callback(err, null);
 | 
			
		||||
 | 
			
		||||
      if(doc.ok === 0)
 | 
			
		||||
        return callback(new Error("Error with validate command"), null);
 | 
			
		||||
      if(doc.result != null && doc.result.constructor != String)
 | 
			
		||||
        return callback(new Error("Error with validation data"), null);
 | 
			
		||||
      if(doc.result != null && doc.result.match(/exception|corrupt/) != null)
 | 
			
		||||
        return callback(new Error("Error: invalid collection " + collectionName), null);
 | 
			
		||||
      if(doc.valid != null && !doc.valid)
 | 
			
		||||
        return callback(new Error("Error: invalid collection " + collectionName), null);
 | 
			
		||||
 | 
			
		||||
      return callback(null, doc);
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * List the available databases
 | 
			
		||||
   *
 | 
			
		||||
   * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from listDatabases or null if an error occured.
 | 
			
		||||
   * @return {null} Returns no result
 | 
			
		||||
   * @api public
 | 
			
		||||
   */
 | 
			
		||||
  this.listDatabases = function(callback) {
 | 
			
		||||
    // Execute the listAllDatabases command
 | 
			
		||||
    db.executeDbAdminCommand({listDatabases:1}, {}, function(err, doc) {
 | 
			
		||||
      if(err != null) return callback(err, null);
 | 
			
		||||
      return callback(null, doc.documents[0]);
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Get ReplicaSet status
 | 
			
		||||
   *
 | 
			
		||||
   * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from replSetGetStatus or null if an error occured.
 | 
			
		||||
   * @return {null}
 | 
			
		||||
   * @api public
 | 
			
		||||
   */
 | 
			
		||||
  this.replSetGetStatus = function(callback) {
 | 
			
		||||
    var self = this;
 | 
			
		||||
 | 
			
		||||
    db.executeDbAdminCommand({replSetGetStatus:1}, function(err, doc) {
 | 
			
		||||
      if(err == null && doc.documents[0].ok === 1)
 | 
			
		||||
        return callback(null, doc.documents[0]);
 | 
			
		||||
      if(err) return callback(err, false);
 | 
			
		||||
      return callback(utils.toError(doc.documents[0]), false);
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
exports.Admin = Admin;
 | 
			
		||||
							
								
								
									
										191
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/aggregation_cursor.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										191
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/aggregation_cursor.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,191 @@
 | 
			
		||||
var ReadPreference = require('./connection/read_preference').ReadPreference
 | 
			
		||||
	, Readable = require('stream').Readable || require('readable-stream').Readable
 | 
			
		||||
	, CommandCursor = require('./command_cursor').CommandCursor
 | 
			
		||||
	, utils = require('./utils')
 | 
			
		||||
	, shared = require('./collection/shared')
 | 
			
		||||
	, inherits = require('util').inherits;
 | 
			
		||||
 | 
			
		||||
var AggregationCursor = function(collection, serverCapabilities, options) {	
 | 
			
		||||
	var pipe = [];
 | 
			
		||||
	var self = this;
 | 
			
		||||
	var results = null;	
 | 
			
		||||
	var _cursor_options = {};
 | 
			
		||||
	// Ensure we have options set up
 | 
			
		||||
	options = options == null ? {} : options;
 | 
			
		||||
 | 
			
		||||
	// If a pipeline was provided
 | 
			
		||||
	pipe = Array.isArray(options.pipe) ? options.pipe : pipe;
 | 
			
		||||
	// Set passed in batchSize if provided
 | 
			
		||||
	if(typeof options.batchSize == 'number') _cursor_options.batchSize = options.batchSize;
 | 
			
		||||
	// Get the read Preference
 | 
			
		||||
	var readPreference = shared._getReadConcern(collection, options);
 | 
			
		||||
 | 
			
		||||
	// Set up
 | 
			
		||||
	Readable.call(this, {objectMode: true});
 | 
			
		||||
 | 
			
		||||
	// Contains connection
 | 
			
		||||
	var connection = null;
 | 
			
		||||
 | 
			
		||||
	// Set the read preference
 | 
			
		||||
	var _options = { 
 | 
			
		||||
		readPreference: readPreference
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	// Actual command
 | 
			
		||||
	var command = {
 | 
			
		||||
			aggregate: collection.collectionName
 | 
			
		||||
		, pipeline: pipe
 | 
			
		||||
		, cursor: _cursor_options
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// If allowDiskUse is set
 | 
			
		||||
	if(typeof options.allowDiskUse == 'boolean') 
 | 
			
		||||
		command.allowDiskUse = options.allowDiskUse;
 | 
			
		||||
 | 
			
		||||
  // If maxTimeMS is set
 | 
			
		||||
  if(typeof options.maxTimeMS == 'number')
 | 
			
		||||
    command.maxTimeMS = options.maxTimeMS;
 | 
			
		||||
 | 
			
		||||
	// Command cursor (if we support one)
 | 
			
		||||
	var commandCursor = new CommandCursor(collection.db, collection, command);
 | 
			
		||||
 | 
			
		||||
	this.explain = function(callback) {
 | 
			
		||||
		if(typeof callback != 'function') 
 | 
			
		||||
			throw utils.toError("AggregationCursor explain requires a callback function");
 | 
			
		||||
		
 | 
			
		||||
		// Add explain options
 | 
			
		||||
		_options.explain = true;
 | 
			
		||||
		// Execute aggregation pipeline
 | 
			
		||||
		collection.aggregate(pipe, _options, function(err, results) {
 | 
			
		||||
			if(err) return callback(err, null);
 | 
			
		||||
			callback(null, results);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.get = function(callback) {
 | 
			
		||||
		if(typeof callback != 'function') 
 | 
			
		||||
			throw utils.toError("AggregationCursor get requires a callback function");		
 | 
			
		||||
	  // Checkout a connection
 | 
			
		||||
	  var _connection = collection.db.serverConfig.checkoutReader(_options.readPreference);
 | 
			
		||||
	  // Fall back
 | 
			
		||||
		if(!_connection.serverCapabilities.hasAggregationCursor) {
 | 
			
		||||
			return collection.aggregate(pipe, _options, function(err, results) {
 | 
			
		||||
				if(err) return callback(err);
 | 
			
		||||
				callback(null, results);
 | 
			
		||||
			});			
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Execute get using command Cursor
 | 
			
		||||
		commandCursor.get({connection: _connection}, callback);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.getOne = function(callback) {
 | 
			
		||||
		if(typeof callback != 'function') 
 | 
			
		||||
			throw utils.toError("AggregationCursor getOne requires a callback function");		
 | 
			
		||||
		// Set the limit to 1
 | 
			
		||||
		pipe.push({$limit: 1});
 | 
			
		||||
		// For now we have no cursor command so let's just wrap existing results
 | 
			
		||||
		collection.aggregate(pipe, _options, function(err, results) {
 | 
			
		||||
			if(err) return callback(err);
 | 
			
		||||
			callback(null, results[0]);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.each = function(callback) {
 | 
			
		||||
	  // Checkout a connection if we have none
 | 
			
		||||
	  if(!connection)
 | 
			
		||||
	  	connection = collection.db.serverConfig.checkoutReader(_options.readPreference);
 | 
			
		||||
	  
 | 
			
		||||
	  // Fall back
 | 
			
		||||
		if(!connection.serverCapabilities.hasAggregationCursor) {
 | 
			
		||||
			return collection.aggregate(pipe, _options, function(err, _results) {
 | 
			
		||||
				if(err) return callback(err);
 | 
			
		||||
 | 
			
		||||
				while(_results.length > 0) {
 | 
			
		||||
					callback(null, _results.shift());
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				callback(null, null);
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Execute each using command Cursor
 | 
			
		||||
		commandCursor.each({connection: connection}, function(err, doc) {
 | 
			
		||||
			callback(err, doc);
 | 
			
		||||
		});		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.next = function(callback) {
 | 
			
		||||
		if(typeof callback != 'function') 
 | 
			
		||||
			throw utils.toError("AggregationCursor next requires a callback function");		
 | 
			
		||||
 | 
			
		||||
	  // Checkout a connection if we have none
 | 
			
		||||
	  if(!connection)
 | 
			
		||||
	  	connection = collection.db.serverConfig.checkoutReader(_options.readPreference);
 | 
			
		||||
	  
 | 
			
		||||
	  // Fall back
 | 
			
		||||
		if(!connection.serverCapabilities.hasAggregationCursor) {
 | 
			
		||||
			if(!results) {
 | 
			
		||||
				// For now we have no cursor command so let's just wrap existing results
 | 
			
		||||
				return collection.aggregate(pipe, _options, function(err, _results) {
 | 
			
		||||
					if(err) return callback(err);
 | 
			
		||||
					results = _results;
 | 
			
		||||
	        
 | 
			
		||||
	        // Ensure we don't issue undefined
 | 
			
		||||
	        var item = results.shift();
 | 
			
		||||
	        callback(null, item ? item : null);
 | 
			
		||||
				});			
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
	    // Ensure we don't issue undefined
 | 
			
		||||
	    var item = results.shift();
 | 
			
		||||
	    // Return the item
 | 
			
		||||
	    return callback(null, item ? item : null);
 | 
			
		||||
	  }
 | 
			
		||||
 | 
			
		||||
		// Execute next using command Cursor
 | 
			
		||||
		commandCursor.next({connection: connection}, callback);		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//
 | 
			
		||||
	// Close method
 | 
			
		||||
	//
 | 
			
		||||
	this.close = function(callback) {
 | 
			
		||||
		if(typeof callback != 'function') 
 | 
			
		||||
			throw utils.toError("AggregationCursor close requires a callback function");		
 | 
			
		||||
 | 
			
		||||
	  // Checkout a connection if we have none
 | 
			
		||||
	  if(!connection)
 | 
			
		||||
	  	connection = collection.db.serverConfig.checkoutReader(_options.readPreference);
 | 
			
		||||
 | 
			
		||||
	  // Fall back
 | 
			
		||||
		if(!connection.serverCapabilities.hasAggregationCursor) {
 | 
			
		||||
			return callback(null, null);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Execute next using command Cursor
 | 
			
		||||
		commandCursor.close(callback);		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//
 | 
			
		||||
	// Stream method
 | 
			
		||||
	//
 | 
			
		||||
	this._read = function(n) {
 | 
			
		||||
		self.next(function(err, result) {
 | 
			
		||||
			if(err) {
 | 
			
		||||
				self.emit('error', err);
 | 
			
		||||
				return self.push(null);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			self.push(result);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Inherit from Readable
 | 
			
		||||
if(Readable != null) {
 | 
			
		||||
	inherits(AggregationCursor, Readable);	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Exports the Aggregation Framework
 | 
			
		||||
exports.AggregationCursor = AggregationCursor;
 | 
			
		||||
							
								
								
									
										81
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/auth/mongodb_cr.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										81
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/auth/mongodb_cr.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,81 @@
 | 
			
		||||
var DbCommand = require('../commands/db_command').DbCommand
 | 
			
		||||
  , utils = require('../utils')
 | 
			
		||||
  , crypto = require('crypto');
 | 
			
		||||
 | 
			
		||||
var authenticate = function(db, username, password, authdb, options, callback) {
 | 
			
		||||
  var numberOfConnections = 0;
 | 
			
		||||
  var errorObject = null;
 | 
			
		||||
  var numberOfValidConnections = 0;
 | 
			
		||||
  var credentialsValid = false;
 | 
			
		||||
  options = options || {};
 | 
			
		||||
 | 
			
		||||
  if(options['connection'] != null) {
 | 
			
		||||
    //if a connection was explicitly passed on options, then we have only one...
 | 
			
		||||
    numberOfConnections = 1;
 | 
			
		||||
  } else {
 | 
			
		||||
    // Get the amount of connections in the pool to ensure we have authenticated all comments
 | 
			
		||||
    numberOfConnections = db.serverConfig.allRawConnections().length;
 | 
			
		||||
    options['onAll'] = true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Return connection option
 | 
			
		||||
  options.returnConnection = true;
 | 
			
		||||
 | 
			
		||||
  // Execute nonce command
 | 
			
		||||
  db.command({'getnonce':1}, options, function(err, result, connection) {
 | 
			
		||||
    // Execute on all the connections
 | 
			
		||||
    if(err == null) {
 | 
			
		||||
      // Nonce used to make authentication request with md5 hash
 | 
			
		||||
      var nonce = result.nonce;
 | 
			
		||||
 | 
			
		||||
      // Use node md5 generator
 | 
			
		||||
      var md5 = crypto.createHash('md5');
 | 
			
		||||
      // Generate keys used for authentication
 | 
			
		||||
      md5.update(username + ":mongo:" + password);
 | 
			
		||||
      var hash_password = md5.digest('hex');
 | 
			
		||||
      // Final key
 | 
			
		||||
      md5 = crypto.createHash('md5');
 | 
			
		||||
      md5.update(nonce + username + hash_password);
 | 
			
		||||
      var key = md5.digest('hex');
 | 
			
		||||
      
 | 
			
		||||
      // Creat cmd
 | 
			
		||||
      var cmd = {'authenticate':1, 'user':username, 'nonce':nonce, 'key':key};
 | 
			
		||||
 | 
			
		||||
      // Execute command
 | 
			
		||||
      db.db(authdb).command(cmd, {connection:connection}, function(err, result) {
 | 
			
		||||
        // Count down
 | 
			
		||||
        numberOfConnections = numberOfConnections - 1;
 | 
			
		||||
        
 | 
			
		||||
        // Ensure we save any error
 | 
			
		||||
        if(err) { 
 | 
			
		||||
          errorObject = err;
 | 
			
		||||
        } else {
 | 
			
		||||
          credentialsValid = true;
 | 
			
		||||
          numberOfValidConnections = numberOfValidConnections + 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Work around the case where the number of connections are 0
 | 
			
		||||
        if(numberOfConnections <= 0 && typeof callback == 'function') {
 | 
			
		||||
          var internalCallback = callback;
 | 
			
		||||
          callback = null;
 | 
			
		||||
 | 
			
		||||
          if(errorObject == null && credentialsValid) {
 | 
			
		||||
            db.serverConfig.auth.add('MONGODB-CR', db.databaseName, username, password, authdb);
 | 
			
		||||
            // Return callback
 | 
			
		||||
            internalCallback(errorObject, true);
 | 
			
		||||
          } else if(numberOfValidConnections > 0 && numberOfValidConnections != numberOfConnections
 | 
			
		||||
            && credentialsValid) {
 | 
			
		||||
              // One or more servers failed on auth (f.ex secondary hanging on foreground indexing)
 | 
			
		||||
              db.serverConfig.auth.add('MONGODB-CR', db.databaseName, username, password, authdb);
 | 
			
		||||
              // Return callback
 | 
			
		||||
              internalCallback(errorObject, true);
 | 
			
		||||
          } else {
 | 
			
		||||
            internalCallback(errorObject, false);
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.authenticate = authenticate;
 | 
			
		||||
							
								
								
									
										172
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/auth/mongodb_gssapi.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										172
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/auth/mongodb_gssapi.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,172 @@
 | 
			
		||||
var DbCommand = require('../commands/db_command').DbCommand
 | 
			
		||||
  , utils = require('../utils')
 | 
			
		||||
  , format = require('util').format;
 | 
			
		||||
 | 
			
		||||
// Kerberos class
 | 
			
		||||
var Kerberos = null;
 | 
			
		||||
var MongoAuthProcess = null;
 | 
			
		||||
// Try to grab the Kerberos class
 | 
			
		||||
try {
 | 
			
		||||
  Kerberos = require('kerberos').Kerberos
 | 
			
		||||
  // Authentication process for Mongo
 | 
			
		||||
  MongoAuthProcess = require('kerberos').processes.MongoAuthProcess
 | 
			
		||||
} catch(err) {}
 | 
			
		||||
 | 
			
		||||
var authenticate = function(db, username, password, authdb, options, callback) {
 | 
			
		||||
  var numberOfConnections = 0;
 | 
			
		||||
  var errorObject = null;  
 | 
			
		||||
  var numberOfValidConnections = 0;
 | 
			
		||||
  var credentialsValid = false;
 | 
			
		||||
  options = options || {};
 | 
			
		||||
  
 | 
			
		||||
  // We don't have the Kerberos library
 | 
			
		||||
  if(Kerberos == null) return callback(new Error("Kerberos library is not installed"));  
 | 
			
		||||
 | 
			
		||||
  if(options['connection'] != null) {
 | 
			
		||||
    //if a connection was explicitly passed on options, then we have only one...
 | 
			
		||||
    numberOfConnections = 1;
 | 
			
		||||
  } else {
 | 
			
		||||
    // Get the amount of connections in the pool to ensure we have authenticated all comments
 | 
			
		||||
    numberOfConnections = db.serverConfig.allRawConnections().length;
 | 
			
		||||
    options['onAll'] = true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Grab all the connections
 | 
			
		||||
  var connections = options['connection'] != null ? [options['connection']] : db.serverConfig.allRawConnections();
 | 
			
		||||
  var gssapiServiceName = options['gssapiServiceName'] || 'mongodb';
 | 
			
		||||
 | 
			
		||||
  // Authenticate all connections
 | 
			
		||||
  for(var i = 0; i < numberOfConnections; i++) {
 | 
			
		||||
 | 
			
		||||
    // Start Auth process for a connection
 | 
			
		||||
    GSSAPIInitialize(db, username, password, authdb, gssapiServiceName, connections[i], function(err, result) {
 | 
			
		||||
      // Adjust number of connections left to connect
 | 
			
		||||
      numberOfConnections = numberOfConnections - 1;
 | 
			
		||||
 | 
			
		||||
      // Ensure we save any error
 | 
			
		||||
      if(err) { 
 | 
			
		||||
        errorObject = err;
 | 
			
		||||
      } else {
 | 
			
		||||
        credentialsValid = true;
 | 
			
		||||
        numberOfValidConnections = numberOfValidConnections + 1;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Work around the case where the number of connections are 0
 | 
			
		||||
      if(numberOfConnections <= 0 && typeof callback == 'function') {
 | 
			
		||||
        var internalCallback = callback;
 | 
			
		||||
        callback = null;
 | 
			
		||||
 | 
			
		||||
        // We are done
 | 
			
		||||
        if(errorObject == null && numberOfConnections == 0) {
 | 
			
		||||
          // We authenticated correctly save the credentials
 | 
			
		||||
          db.serverConfig.auth.add('GSSAPI', db.databaseName, username, password, authdb, gssapiServiceName);
 | 
			
		||||
          // Return valid callback
 | 
			
		||||
          return internalCallback(null, true);
 | 
			
		||||
        } else if(numberOfValidConnections > 0 && numberOfValidConnections != numberOfConnections
 | 
			
		||||
          && credentialsValid) {
 | 
			
		||||
            // We authenticated correctly save the credentials
 | 
			
		||||
            db.serverConfig.auth.add('GSSAPI', db.databaseName, username, password, authdb, gssapiServiceName);
 | 
			
		||||
            // Return valid callback
 | 
			
		||||
            return internalCallback(null, true);
 | 
			
		||||
        } else {
 | 
			
		||||
          return internalCallback(errorObject, false);        
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    });    
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Initialize step
 | 
			
		||||
var GSSAPIInitialize = function(db, username, password, authdb, gssapiServiceName, connection, callback) {
 | 
			
		||||
  // Create authenticator
 | 
			
		||||
  var mongo_auth_process = new MongoAuthProcess(connection.socketOptions.host, connection.socketOptions.port, gssapiServiceName);
 | 
			
		||||
 | 
			
		||||
  // Perform initialization
 | 
			
		||||
  mongo_auth_process.init(username, password, function(err, context) {
 | 
			
		||||
    if(err) return callback(err, false);
 | 
			
		||||
 | 
			
		||||
    // Perform the first step
 | 
			
		||||
    mongo_auth_process.transition('', function(err, payload) {
 | 
			
		||||
      if(err) return callback(err, false);
 | 
			
		||||
 | 
			
		||||
      // Call the next db step
 | 
			
		||||
      MongoDBGSSAPIFirstStep(mongo_auth_process, payload, db, username, password, authdb, connection, callback);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Perform first step against mongodb
 | 
			
		||||
var MongoDBGSSAPIFirstStep = function(mongo_auth_process, payload, db, username, password, authdb, connection, callback) {
 | 
			
		||||
  // Build the sasl start command
 | 
			
		||||
  var command = {
 | 
			
		||||
      saslStart: 1
 | 
			
		||||
    , mechanism: 'GSSAPI'
 | 
			
		||||
    , payload: payload
 | 
			
		||||
    , autoAuthorize: 1
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // Execute first sasl step
 | 
			
		||||
  db._executeQueryCommand(DbCommand.createDbCommand(db, command, {}, '$external'), {connection:connection}, function(err, doc) {
 | 
			
		||||
    if(err) return callback(err, false);
 | 
			
		||||
    // Get the payload
 | 
			
		||||
    doc = doc.documents[0];
 | 
			
		||||
    var db_payload = doc.payload;
 | 
			
		||||
 | 
			
		||||
    mongo_auth_process.transition(doc.payload, function(err, payload) {
 | 
			
		||||
      if(err) return callback(err, false);
 | 
			
		||||
 | 
			
		||||
      // MongoDB API Second Step
 | 
			
		||||
      MongoDBGSSAPISecondStep(mongo_auth_process, payload, doc, db, username, password, authdb, connection, callback);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Perform first step against mongodb
 | 
			
		||||
var MongoDBGSSAPISecondStep = function(mongo_auth_process, payload, doc, db, username, password, authdb, connection, callback) {
 | 
			
		||||
  // Build Authentication command to send to MongoDB
 | 
			
		||||
  var command = {
 | 
			
		||||
      saslContinue: 1
 | 
			
		||||
    , conversationId: doc.conversationId
 | 
			
		||||
    , payload: payload
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // Execute the command
 | 
			
		||||
  db._executeQueryCommand(DbCommand.createDbCommand(db, command, {}, '$external'), {connection:connection}, function(err, doc) {
 | 
			
		||||
    if(err) return callback(err, false);
 | 
			
		||||
 | 
			
		||||
    // Get the result document
 | 
			
		||||
    doc = doc.documents[0];
 | 
			
		||||
 | 
			
		||||
    // Call next transition for kerberos
 | 
			
		||||
    mongo_auth_process.transition(doc.payload, function(err, payload) {
 | 
			
		||||
      if(err) return callback(err, false);
 | 
			
		||||
 | 
			
		||||
      // Call the last and third step
 | 
			
		||||
      MongoDBGSSAPIThirdStep(mongo_auth_process, payload, doc, db, username, password, authdb, connection, callback);
 | 
			
		||||
    });    
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var MongoDBGSSAPIThirdStep = function(mongo_auth_process, payload, doc, db, username, password, authdb, connection, callback) {
 | 
			
		||||
  // Build final command
 | 
			
		||||
  var command = {
 | 
			
		||||
      saslContinue: 1
 | 
			
		||||
    , conversationId: doc.conversationId
 | 
			
		||||
    , payload: payload
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // Let's finish the auth process against mongodb
 | 
			
		||||
  db._executeQueryCommand(DbCommand.createDbCommand(db, command, {}, '$external'), {connection:connection}, function(err, doc) {
 | 
			
		||||
    if(err) return callback(err, false);
 | 
			
		||||
 | 
			
		||||
    mongo_auth_process.transition(null, function(err, payload) {
 | 
			
		||||
      if(err) return callback(err, false);
 | 
			
		||||
      callback(null, true);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.authenticate = authenticate;
 | 
			
		||||
							
								
								
									
										79
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/auth/mongodb_plain.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										79
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/auth/mongodb_plain.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,79 @@
 | 
			
		||||
var DbCommand = require('../commands/db_command').DbCommand
 | 
			
		||||
  , utils = require('../utils')
 | 
			
		||||
  , crypto = require('crypto')
 | 
			
		||||
  , Binary = require('bson').Binary
 | 
			
		||||
  , format = require('util').format;
 | 
			
		||||
 | 
			
		||||
var authenticate = function(db, username, password, options, callback) {
 | 
			
		||||
  var numberOfConnections = 0;
 | 
			
		||||
  var errorObject = null;
 | 
			
		||||
  var numberOfValidConnections = 0;
 | 
			
		||||
  var credentialsValid = false;
 | 
			
		||||
  options = options || {};
 | 
			
		||||
  
 | 
			
		||||
  if(options['connection'] != null) {
 | 
			
		||||
    //if a connection was explicitly passed on options, then we have only one...
 | 
			
		||||
    numberOfConnections = 1;
 | 
			
		||||
  } else {
 | 
			
		||||
    // Get the amount of connections in the pool to ensure we have authenticated all comments
 | 
			
		||||
    numberOfConnections = db.serverConfig.allRawConnections().length;
 | 
			
		||||
    options['onAll'] = true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Create payload
 | 
			
		||||
  var payload = new Binary(format("\x00%s\x00%s", username, password));
 | 
			
		||||
 | 
			
		||||
  // Let's start the sasl process
 | 
			
		||||
  var command = {
 | 
			
		||||
      saslStart: 1
 | 
			
		||||
    , mechanism: 'PLAIN'
 | 
			
		||||
    , payload: payload
 | 
			
		||||
    , autoAuthorize: 1
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // Grab all the connections
 | 
			
		||||
  var connections = options['connection'] != null ? [options['connection']] : db.serverConfig.allRawConnections();
 | 
			
		||||
 | 
			
		||||
  // Authenticate all connections
 | 
			
		||||
  for(var i = 0; i < numberOfConnections; i++) {
 | 
			
		||||
    var connection = connections[i];
 | 
			
		||||
    // Execute first sasl step
 | 
			
		||||
    db._executeQueryCommand(DbCommand.createDbCommand(db, command, {}, '$external'), {connection:connection}, function(err, result) {
 | 
			
		||||
      // Count down
 | 
			
		||||
      numberOfConnections = numberOfConnections - 1;
 | 
			
		||||
 | 
			
		||||
      // Ensure we save any error
 | 
			
		||||
      if(err) {
 | 
			
		||||
        errorObject = err;
 | 
			
		||||
      } else if(result.documents[0].err != null || result.documents[0].errmsg != null){
 | 
			
		||||
        errorObject = utils.toError(result.documents[0]);
 | 
			
		||||
      } else {
 | 
			
		||||
        credentialsValid = true;
 | 
			
		||||
        numberOfValidConnections = numberOfValidConnections + 1;        
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Work around the case where the number of connections are 0
 | 
			
		||||
      if(numberOfConnections <= 0 && typeof callback == 'function') {
 | 
			
		||||
        var internalCallback = callback;
 | 
			
		||||
        callback = null;
 | 
			
		||||
 | 
			
		||||
        if(errorObject == null && credentialsValid) {
 | 
			
		||||
          // We authenticated correctly save the credentials
 | 
			
		||||
          db.serverConfig.auth.add('PLAIN', db.databaseName, username, password);
 | 
			
		||||
          // Return callback
 | 
			
		||||
          internalCallback(errorObject, true);
 | 
			
		||||
        } else if(numberOfValidConnections > 0 && numberOfValidConnections != numberOfConnections
 | 
			
		||||
          && credentialsValid) {
 | 
			
		||||
            // We authenticated correctly save the credentials
 | 
			
		||||
            db.serverConfig.auth.add('PLAIN', db.databaseName, username, password);
 | 
			
		||||
            // Return callback
 | 
			
		||||
            internalCallback(errorObject, true);
 | 
			
		||||
        } else {
 | 
			
		||||
          internalCallback(errorObject, false);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.authenticate = authenticate;
 | 
			
		||||
							
								
								
									
										251
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/auth/mongodb_scram.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										251
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/auth/mongodb_scram.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,251 @@
 | 
			
		||||
var DbCommand = require('../commands/db_command').DbCommand
 | 
			
		||||
  , utils = require('../utils')
 | 
			
		||||
  , crypto = require('crypto')
 | 
			
		||||
  , Binary = require('bson').Binary
 | 
			
		||||
  , f = require('util').format;
 | 
			
		||||
 | 
			
		||||
var authenticate = function(db, username, password, authdb, options, callback) {
 | 
			
		||||
  var numberOfConnections = 0;
 | 
			
		||||
  var errorObject = null;
 | 
			
		||||
  var numberOfValidConnections = 0;
 | 
			
		||||
  var credentialsValid = false;
 | 
			
		||||
  options = options || {};
 | 
			
		||||
 | 
			
		||||
  // Grab all the connections
 | 
			
		||||
  var connections = options['connection'] != null ? [options['connection']] : db.serverConfig.allRawConnections().slice(0);
 | 
			
		||||
  if(connections.length > 1) {
 | 
			
		||||
    options['onAll'] = true; 
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Total connections
 | 
			
		||||
  var count = connections.length;
 | 
			
		||||
  if(count == 0) return callback(null, null);
 | 
			
		||||
 | 
			
		||||
  // Valid connections
 | 
			
		||||
  var numberOfValidConnections = 0;
 | 
			
		||||
  var credentialsValid = false;
 | 
			
		||||
  var errorObject = null;
 | 
			
		||||
 | 
			
		||||
  // For each connection we need to authenticate
 | 
			
		||||
  while(connections.length > 0) {    
 | 
			
		||||
    // Execute MongoCR
 | 
			
		||||
    var executeScram = function(connection) {
 | 
			
		||||
      // Clean up the user
 | 
			
		||||
      username = username.replace('=', "=3D").replace(',', '=2C');
 | 
			
		||||
 | 
			
		||||
      // Create a random nonce
 | 
			
		||||
      var nonce = crypto.randomBytes(24).toString('base64');
 | 
			
		||||
      // var nonce = 'MsQUY9iw0T9fx2MUEz6LZPwGuhVvWAhc'
 | 
			
		||||
      var firstBare = f("n=%s,r=%s", username, nonce);
 | 
			
		||||
 | 
			
		||||
      // Build command structure
 | 
			
		||||
      var cmd = {
 | 
			
		||||
          saslStart: 1
 | 
			
		||||
        , mechanism: 'SCRAM-SHA-1'
 | 
			
		||||
        , payload: new Binary(f("n,,%s", firstBare))
 | 
			
		||||
        , autoAuthorize: 1
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Handle the error
 | 
			
		||||
      var handleError = function(err, r) {
 | 
			
		||||
        if(err) {
 | 
			
		||||
          errorObject = err; return false;
 | 
			
		||||
        } else if(r['$err']) {
 | 
			
		||||
          errorObject = r; return false;
 | 
			
		||||
        } else if(r['errmsg']) {
 | 
			
		||||
          errorObject = r; return false;
 | 
			
		||||
        } else {
 | 
			
		||||
          credentialsValid = true;
 | 
			
		||||
          numberOfValidConnections = numberOfValidConnections + 1;            
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return true
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Finish up
 | 
			
		||||
      var finish = function(_count, _numberOfValidConnections) {
 | 
			
		||||
        if(_count == 0 && _numberOfValidConnections > 0) {
 | 
			
		||||
          db.serverConfig.auth.add('SCRAM-SHA-1', db.databaseName, username, password, authdb);
 | 
			
		||||
          // Return correct authentication
 | 
			
		||||
          return callback(null, true);
 | 
			
		||||
        } else if(_count == 0) {
 | 
			
		||||
          if(errorObject == null) errorObject = utils.toError(f("failed to authenticate using scram"));
 | 
			
		||||
          return callback(errorObject, false);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      var handleEnd = function(_err, _r) {
 | 
			
		||||
        // Handle any error
 | 
			
		||||
        handleError(_err, _r)
 | 
			
		||||
        // Adjust the number of connections
 | 
			
		||||
        count = count - 1;
 | 
			
		||||
        // Execute the finish
 | 
			
		||||
        finish(count, numberOfValidConnections);                
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Execute start sasl command
 | 
			
		||||
      db.db(authdb).command(cmd, { connection: connection }, function(err, r) {
 | 
			
		||||
        // Do we have an error, handle it
 | 
			
		||||
        if(handleError(err, r) == false) {
 | 
			
		||||
          count = count - 1;
 | 
			
		||||
 | 
			
		||||
          if(count == 0 && numberOfValidConnections > 0) {
 | 
			
		||||
            // Store the auth details
 | 
			
		||||
            addAuthSession(new AuthSession(db, username, password));
 | 
			
		||||
            // Return correct authentication
 | 
			
		||||
            return callback(null, true);
 | 
			
		||||
          } else if(count == 0) {
 | 
			
		||||
            if(errorObject == null) errorObject = utils.toError(f("failed to authenticate using scram"));
 | 
			
		||||
            return callback(errorObject, false);
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Get the dictionary
 | 
			
		||||
        var dict = parsePayload(r.payload.value())
 | 
			
		||||
 | 
			
		||||
        // Unpack dictionary
 | 
			
		||||
        var iterations = parseInt(dict.i, 10);
 | 
			
		||||
        var salt = dict.s;
 | 
			
		||||
        var rnonce = dict.r;
 | 
			
		||||
 | 
			
		||||
        // Set up start of proof
 | 
			
		||||
        var withoutProof = f("c=biws,r=%s", rnonce);
 | 
			
		||||
        var passwordDig = passwordDigest(username, password);
 | 
			
		||||
        var saltedPassword = hi(passwordDig
 | 
			
		||||
            , new Buffer(salt, 'base64')
 | 
			
		||||
            , iterations);
 | 
			
		||||
        
 | 
			
		||||
        // Create the client key
 | 
			
		||||
        var hmac = crypto.createHmac('sha1', saltedPassword);
 | 
			
		||||
        hmac.update(new Buffer("Client Key"));
 | 
			
		||||
        var clientKey = hmac.digest();
 | 
			
		||||
 | 
			
		||||
        // Create the stored key
 | 
			
		||||
        var hash = crypto.createHash('sha1');
 | 
			
		||||
        hash.update(clientKey);
 | 
			
		||||
        var storedKey = hash.digest();
 | 
			
		||||
 | 
			
		||||
        // Create the authentication message
 | 
			
		||||
        var authMsg = [firstBare, r.payload.value().toString('base64'), withoutProof].join(',');
 | 
			
		||||
 | 
			
		||||
        // Create client signature
 | 
			
		||||
        var hmac = crypto.createHmac('sha1', storedKey);
 | 
			
		||||
        hmac.update(new Buffer(authMsg));          
 | 
			
		||||
        var clientSig = hmac.digest();
 | 
			
		||||
 | 
			
		||||
        // Create client proof
 | 
			
		||||
        var clientProof = f("p=%s", new Buffer(xor(clientKey, clientSig)).toString('base64'));
 | 
			
		||||
 | 
			
		||||
        // Create client final
 | 
			
		||||
        var clientFinal = [withoutProof, clientProof].join(',');
 | 
			
		||||
 | 
			
		||||
        // Generate server key
 | 
			
		||||
        var hmac = crypto.createHmac('sha1', saltedPassword);
 | 
			
		||||
        hmac.update(new Buffer('Server Key'))
 | 
			
		||||
        var serverKey = hmac.digest();
 | 
			
		||||
 | 
			
		||||
        // Generate server signature
 | 
			
		||||
        var hmac = crypto.createHmac('sha1', serverKey);
 | 
			
		||||
        hmac.update(new Buffer(authMsg))
 | 
			
		||||
        var serverSig = hmac.digest();
 | 
			
		||||
 | 
			
		||||
        //
 | 
			
		||||
        // Create continue message
 | 
			
		||||
        var cmd = {
 | 
			
		||||
            saslContinue: 1
 | 
			
		||||
          , conversationId: r.conversationId
 | 
			
		||||
          , payload: new Binary(new Buffer(clientFinal))
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //
 | 
			
		||||
        // Execute sasl continue
 | 
			
		||||
        db.db(authdb).command(cmd, { connection: connection }, function(err, r) {
 | 
			
		||||
          if(err) return handleEnd(err, r);
 | 
			
		||||
          if(r && r.done == false) {
 | 
			
		||||
            var cmd = {
 | 
			
		||||
                saslContinue: 1
 | 
			
		||||
              , conversationId: r.conversationId
 | 
			
		||||
              , payload: new Buffer(0)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            db.db(authdb).command(cmd, { connection: connection }, function(err, r) {
 | 
			
		||||
              handleEnd(err, r);
 | 
			
		||||
            });
 | 
			
		||||
          } else {
 | 
			
		||||
            handleEnd(err, r);
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Get the connection
 | 
			
		||||
    executeScram(connections.shift());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var parsePayload = function(payload) {
 | 
			
		||||
  var dict = {};
 | 
			
		||||
  var parts = payload.split(',');
 | 
			
		||||
 | 
			
		||||
  for(var i = 0; i < parts.length; i++) {
 | 
			
		||||
    var valueParts = parts[i].split('=');
 | 
			
		||||
    dict[valueParts[0]] = valueParts[1];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return dict;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var passwordDigest = function(username, password) {
 | 
			
		||||
  if(typeof username != 'string') throw utils.toError("username must be a string");
 | 
			
		||||
  if(typeof password != 'string') throw utils.toError("password must be a string");
 | 
			
		||||
  if(password.length == 0) throw utils.toError("password cannot be empty");
 | 
			
		||||
  // Use node md5 generator
 | 
			
		||||
  var md5 = crypto.createHash('md5');
 | 
			
		||||
  // Generate keys used for authentication
 | 
			
		||||
  md5.update(username + ":mongo:" + password);
 | 
			
		||||
  return md5.digest('hex');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// XOR two buffers
 | 
			
		||||
var xor = function(a, b) {
 | 
			
		||||
  if (!Buffer.isBuffer(a)) a = new Buffer(a)
 | 
			
		||||
  if (!Buffer.isBuffer(b)) b = new Buffer(b)
 | 
			
		||||
  var res = []
 | 
			
		||||
  if (a.length > b.length) {
 | 
			
		||||
    for (var i = 0; i < b.length; i++) {
 | 
			
		||||
      res.push(a[i] ^ b[i])
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    for (var i = 0; i < a.length; i++) {
 | 
			
		||||
      res.push(a[i] ^ b[i])
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return new Buffer(res);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Create a final digest
 | 
			
		||||
var hi = function(data, salt, iterations) {
 | 
			
		||||
  // Create digest
 | 
			
		||||
  var digest = function(msg) {
 | 
			
		||||
    var hmac = crypto.createHmac('sha1', data);
 | 
			
		||||
    hmac.update(msg);
 | 
			
		||||
    var result = hmac.digest()
 | 
			
		||||
    return result;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Create variables
 | 
			
		||||
  salt = Buffer.concat([salt, new Buffer('\x00\x00\x00\x01')])
 | 
			
		||||
  var ui = digest(salt);
 | 
			
		||||
  var u1 = ui;
 | 
			
		||||
  
 | 
			
		||||
  for(var i = 0; i < iterations - 1; i++) {
 | 
			
		||||
    u1 = digest(u1);
 | 
			
		||||
    ui = xor(ui, u1);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return ui;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.authenticate = authenticate;
 | 
			
		||||
							
								
								
									
										156
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/auth/mongodb_sspi.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										156
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/auth/mongodb_sspi.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,156 @@
 | 
			
		||||
var DbCommand = require('../commands/db_command').DbCommand
 | 
			
		||||
  , utils = require('../utils')
 | 
			
		||||
  , format = require('util').format;
 | 
			
		||||
 | 
			
		||||
// Kerberos class
 | 
			
		||||
var Kerberos = null;
 | 
			
		||||
var MongoAuthProcess = null;
 | 
			
		||||
// Try to grab the Kerberos class
 | 
			
		||||
try {
 | 
			
		||||
  Kerberos = require('kerberos').Kerberos
 | 
			
		||||
  // Authentication process for Mongo
 | 
			
		||||
  MongoAuthProcess = require('kerberos').processes.MongoAuthProcess
 | 
			
		||||
} catch(err) {}
 | 
			
		||||
 | 
			
		||||
var authenticate = function(db, username, password, authdb, options, callback) {
 | 
			
		||||
  var numberOfConnections = 0;
 | 
			
		||||
  var errorObject = null;  
 | 
			
		||||
  var numberOfValidConnections = 0;
 | 
			
		||||
  var credentialsValid = false;
 | 
			
		||||
  options = options || {};
 | 
			
		||||
 | 
			
		||||
  // We don't have the Kerberos library
 | 
			
		||||
  if(Kerberos == null) return callback(new Error("Kerberos library is not installed"));
 | 
			
		||||
 | 
			
		||||
  if(options['connection'] != null) {
 | 
			
		||||
    //if a connection was explicitly passed on options, then we have only one...
 | 
			
		||||
    numberOfConnections = 1;
 | 
			
		||||
  } else {
 | 
			
		||||
    // Get the amount of connections in the pool to ensure we have authenticated all comments
 | 
			
		||||
    numberOfConnections = db.serverConfig.allRawConnections().length;
 | 
			
		||||
    options['onAll'] = true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Set the sspi server name
 | 
			
		||||
  var gssapiServiceName = options['gssapiServiceName'] || 'mongodb';
 | 
			
		||||
 | 
			
		||||
  // Grab all the connections
 | 
			
		||||
  var connections = db.serverConfig.allRawConnections();
 | 
			
		||||
  
 | 
			
		||||
  // Authenticate all connections
 | 
			
		||||
  for(var i = 0; i < numberOfConnections; i++) {
 | 
			
		||||
    // Start Auth process for a connection
 | 
			
		||||
    SSIPAuthenticate(db, username, password, authdb, gssapiServiceName, connections[i], function(err, result) {
 | 
			
		||||
      // Adjust number of connections left to connect
 | 
			
		||||
      numberOfConnections = numberOfConnections - 1;
 | 
			
		||||
 | 
			
		||||
      // Ensure we save any error
 | 
			
		||||
      if(err) { 
 | 
			
		||||
        errorObject = err;
 | 
			
		||||
      } else {
 | 
			
		||||
        credentialsValid = true;
 | 
			
		||||
        numberOfValidConnections = numberOfValidConnections + 1;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Work around the case where the number of connections are 0
 | 
			
		||||
      if(numberOfConnections <= 0 && typeof callback == 'function') {
 | 
			
		||||
        var internalCallback = callback;
 | 
			
		||||
        callback = null;
 | 
			
		||||
 | 
			
		||||
        if(errorObject == null) {
 | 
			
		||||
          // We authenticated correctly save the credentials
 | 
			
		||||
          db.serverConfig.auth.add('GSSAPI', db.databaseName, username, password, authdb, gssapiServiceName);
 | 
			
		||||
          // Return valid callback
 | 
			
		||||
          return internalCallback(null, true);          
 | 
			
		||||
        } else if(numberOfValidConnections > 0 && numberOfValidConnections != numberOfConnections
 | 
			
		||||
          && credentialsValid) {
 | 
			
		||||
            // We authenticated correctly save the credentials
 | 
			
		||||
            db.serverConfig.auth.add('GSSAPI', db.databaseName, username, password, authdb, gssapiServiceName);
 | 
			
		||||
            // Return valid callback
 | 
			
		||||
            return internalCallback(null, true);                    
 | 
			
		||||
        } else {
 | 
			
		||||
          return internalCallback(errorObject, false);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    });    
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var SSIPAuthenticate = function(db, username, password, authdb, service_name, connection, callback) {
 | 
			
		||||
  // --------------------------------------------------------------
 | 
			
		||||
  // Async Version
 | 
			
		||||
  // --------------------------------------------------------------
 | 
			
		||||
  var command = {
 | 
			
		||||
      saslStart: 1
 | 
			
		||||
    , mechanism: 'GSSAPI'
 | 
			
		||||
    , payload: ''
 | 
			
		||||
    , autoAuthorize: 1
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // Create authenticator
 | 
			
		||||
  var mongo_auth_process = new MongoAuthProcess(connection.socketOptions.host, connection.socketOptions.port, service_name);
 | 
			
		||||
 | 
			
		||||
  // Execute first sasl step
 | 
			
		||||
  db._executeQueryCommand(DbCommand.createDbCommand(db, command, {}, '$external'), {connection:connection}, function(err, doc) {
 | 
			
		||||
    if(err) return callback(err);
 | 
			
		||||
    doc = doc.documents[0];
 | 
			
		||||
 | 
			
		||||
    mongo_auth_process.init(username, password, function(err) {
 | 
			
		||||
      if(err) return callback(err);
 | 
			
		||||
 | 
			
		||||
      mongo_auth_process.transition(doc.payload, function(err, payload) {
 | 
			
		||||
        if(err) return callback(err);
 | 
			
		||||
 | 
			
		||||
        // Perform the next step against mongod
 | 
			
		||||
        var command = {
 | 
			
		||||
            saslContinue: 1
 | 
			
		||||
          , conversationId: doc.conversationId
 | 
			
		||||
          , payload: payload
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // Execute the command
 | 
			
		||||
        db._executeQueryCommand(DbCommand.createDbCommand(db, command, {}, '$external'), {connection:connection}, function(err, doc) {
 | 
			
		||||
          if(err) return callback(err);
 | 
			
		||||
          doc = doc.documents[0];
 | 
			
		||||
 | 
			
		||||
          mongo_auth_process.transition(doc.payload, function(err, payload) {
 | 
			
		||||
            if(err) return callback(err);
 | 
			
		||||
 | 
			
		||||
            // Perform the next step against mongod
 | 
			
		||||
            var command = {
 | 
			
		||||
                saslContinue: 1
 | 
			
		||||
              , conversationId: doc.conversationId
 | 
			
		||||
              , payload: payload
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            // Execute the command
 | 
			
		||||
            db._executeQueryCommand(DbCommand.createDbCommand(db, command, {}, '$external'), {connection:connection}, function(err, doc) {
 | 
			
		||||
              if(err) return callback(err);
 | 
			
		||||
              doc = doc.documents[0];
 | 
			
		||||
              
 | 
			
		||||
              mongo_auth_process.transition(doc.payload, function(err, payload) {
 | 
			
		||||
                // Perform the next step against mongod
 | 
			
		||||
                var command = {
 | 
			
		||||
                    saslContinue: 1
 | 
			
		||||
                  , conversationId: doc.conversationId
 | 
			
		||||
                  , payload: payload
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                // Execute the command
 | 
			
		||||
                db._executeQueryCommand(DbCommand.createDbCommand(db, command, {}, '$external'), {connection:connection}, function(err, doc) {
 | 
			
		||||
                  if(err) return callback(err);
 | 
			
		||||
                  doc = doc.documents[0];
 | 
			
		||||
 | 
			
		||||
                  if(doc.done) return callback(null, true);
 | 
			
		||||
                  callback(new Error("Authentication failed"), false);
 | 
			
		||||
                });        
 | 
			
		||||
              });
 | 
			
		||||
            });
 | 
			
		||||
          });
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.authenticate = authenticate;
 | 
			
		||||
							
								
								
									
										68
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/auth/mongodb_x509.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										68
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/auth/mongodb_x509.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
var DbCommand = require('../commands/db_command').DbCommand
 | 
			
		||||
  , utils = require('../utils')
 | 
			
		||||
  , Binary = require('bson').Binary
 | 
			
		||||
  , format = require('util').format;
 | 
			
		||||
 | 
			
		||||
var authenticate = function(db, username, password, options, callback, t) {
 | 
			
		||||
  var numberOfConnections = 0;
 | 
			
		||||
  var errorObject = null;
 | 
			
		||||
  var numberOfValidConnections = 0;
 | 
			
		||||
  var credentialsValid = false;
 | 
			
		||||
  options = options || {};
 | 
			
		||||
  
 | 
			
		||||
  if(options['connection'] != null) {
 | 
			
		||||
    //if a connection was explicitly passed on options, then we have only one...
 | 
			
		||||
    numberOfConnections = 1;
 | 
			
		||||
  } else {
 | 
			
		||||
    // Get the amount of connections in the pool to ensure we have authenticated all comments
 | 
			
		||||
    numberOfConnections = db.serverConfig.allRawConnections().length;
 | 
			
		||||
    options['onAll'] = true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Let's start the sasl process
 | 
			
		||||
  var command = {
 | 
			
		||||
      authenticate: 1
 | 
			
		||||
    , mechanism: 'MONGODB-X509'
 | 
			
		||||
    , user: username
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // Grab all the connections
 | 
			
		||||
  var connections = options['connection'] != null ? [options['connection']] : db.serverConfig.allRawConnections();
 | 
			
		||||
 | 
			
		||||
  // Authenticate all connections
 | 
			
		||||
  for(var i = 0; i < numberOfConnections; i++) {
 | 
			
		||||
    var connection = connections[i];
 | 
			
		||||
    // Execute first sasl step
 | 
			
		||||
    db._executeQueryCommand(DbCommand.createDbCommand(db, command, {}, '$external'), {connection:connection}, function(err, result) {
 | 
			
		||||
      // Count down
 | 
			
		||||
      numberOfConnections = numberOfConnections - 1;
 | 
			
		||||
 | 
			
		||||
      // Ensure we save any error
 | 
			
		||||
      if(err) {
 | 
			
		||||
        errorObject = err;
 | 
			
		||||
      } else if(result.documents[0].err != null || result.documents[0].errmsg != null){
 | 
			
		||||
        errorObject = utils.toError(result.documents[0]);
 | 
			
		||||
      } else {
 | 
			
		||||
        credentialsValid = true;
 | 
			
		||||
        numberOfValidConnections = numberOfValidConnections + 1;        
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Work around the case where the number of connections are 0
 | 
			
		||||
      if(numberOfConnections <= 0 && typeof callback == 'function') {
 | 
			
		||||
        var internalCallback = callback;
 | 
			
		||||
        callback = null;
 | 
			
		||||
 | 
			
		||||
        if(errorObject == null && credentialsValid) {
 | 
			
		||||
          // We authenticated correctly save the credentials
 | 
			
		||||
          db.serverConfig.auth.add('MONGODB-X509', db.databaseName, username, password);
 | 
			
		||||
          // Return callback
 | 
			
		||||
          internalCallback(errorObject, true);          
 | 
			
		||||
        } else {
 | 
			
		||||
          internalCallback(errorObject, false);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.authenticate = authenticate;
 | 
			
		||||
							
								
								
									
										688
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/collection.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										688
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/collection.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,688 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Module dependencies.
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
var InsertCommand = require('./commands/insert_command').InsertCommand
 | 
			
		||||
  , QueryCommand = require('./commands/query_command').QueryCommand
 | 
			
		||||
  , DeleteCommand = require('./commands/delete_command').DeleteCommand
 | 
			
		||||
  , UpdateCommand = require('./commands/update_command').UpdateCommand
 | 
			
		||||
  , DbCommand = require('./commands/db_command').DbCommand
 | 
			
		||||
  , ObjectID = require('bson').ObjectID
 | 
			
		||||
  , Code = require('bson').Code
 | 
			
		||||
  , Cursor = require('./cursor').Cursor
 | 
			
		||||
  , utils = require('./utils')
 | 
			
		||||
  , shared = require('./collection/shared')
 | 
			
		||||
  , core = require('./collection/core')
 | 
			
		||||
  , query = require('./collection/query')
 | 
			
		||||
  , index = require('./collection/index')
 | 
			
		||||
  , geo = require('./collection/geo')
 | 
			
		||||
  , commands = require('./collection/commands')
 | 
			
		||||
  , aggregation = require('./collection/aggregation')
 | 
			
		||||
  , unordered = require('./collection/batch/unordered')
 | 
			
		||||
  , ordered = require('./collection/batch/ordered');
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create a new Collection instance (INTERNAL TYPE, do not instantiate directly)
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
 | 
			
		||||
 *  - **slaveOk** {Boolean, default:false}, Allow reads from secondaries.
 | 
			
		||||
 *  - **serializeFunctions** {Boolean, default:false}, serialize functions on the document.
 | 
			
		||||
 *  - **raw** {Boolean, default:false}, perform all operations using raw bson objects.
 | 
			
		||||
 *  - **pkFactory** {Object}, object overriding the basic ObjectID primary key generation.
 | 
			
		||||
 *
 | 
			
		||||
 * @class Represents a Collection
 | 
			
		||||
 * @param {Object} db db instance.
 | 
			
		||||
 * @param {String} collectionName collection name.
 | 
			
		||||
 * @param {Object} [pkFactory] alternative primary key factory.
 | 
			
		||||
 * @param {Object} [options] additional options for the collection.
 | 
			
		||||
 * @return {Object} a collection instance.
 | 
			
		||||
 */
 | 
			
		||||
function Collection (db, collectionName, pkFactory, options) {
 | 
			
		||||
  if(!(this instanceof Collection)) return new Collection(db, collectionName, pkFactory, options);
 | 
			
		||||
 | 
			
		||||
  shared.checkCollectionName(collectionName);
 | 
			
		||||
 | 
			
		||||
  this.db = db;
 | 
			
		||||
  this.collectionName = collectionName;
 | 
			
		||||
  this.internalHint = null;
 | 
			
		||||
  this.opts = options != null && ('object' === typeof options) ? options : {};
 | 
			
		||||
  this.slaveOk = options == null || options.slaveOk == null ? db.slaveOk : options.slaveOk;
 | 
			
		||||
  this.serializeFunctions = options == null || options.serializeFunctions == null ? db.serializeFunctions : options.serializeFunctions;
 | 
			
		||||
  this.raw = options == null || options.raw == null ? db.raw : options.raw;
 | 
			
		||||
 | 
			
		||||
  // Assign the right collection level readPreference
 | 
			
		||||
  if(options && options.readPreference) {
 | 
			
		||||
    this.readPreference = options.readPreference;
 | 
			
		||||
  } else if(this.db.options.readPreference) {
 | 
			
		||||
    this.readPreference = this.db.options.readPreference;
 | 
			
		||||
  } else if(this.db.serverConfig.options.readPreference) {
 | 
			
		||||
    this.readPreference = this.db.serverConfig.options.readPreference;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Set custom primary key factory if provided
 | 
			
		||||
  this.pkFactory = pkFactory == null
 | 
			
		||||
    ? ObjectID
 | 
			
		||||
    : pkFactory;
 | 
			
		||||
 | 
			
		||||
  // Server Capabilities
 | 
			
		||||
  this.serverCapabilities = this.db.serverConfig._serverCapabilities;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Inserts a single document or a an array of documents into MongoDB.
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write
 | 
			
		||||
 *  - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option)
 | 
			
		||||
 *  - **fsync**, (Boolean, default:false) write waits for fsync before returning, from MongoDB 2.6 on, fsync cannot be combined with journal
 | 
			
		||||
 *  - **j**, (Boolean, default:false) write waits for journal sync before returning
 | 
			
		||||
 *  - **continueOnError/keepGoing** {Boolean, default:false}, keep inserting documents even if one document has an error, *mongodb 1.9.1 >*.
 | 
			
		||||
 *  - **serializeFunctions** {Boolean, default:false}, serialize functions on the document.
 | 
			
		||||
 *  - **forceServerObjectId** {Boolean, default:false}, let server assign ObjectId instead of the driver
 | 
			
		||||
 *  - **checkKeys** {Boolean, default:true}, allows for disabling of document key checking (WARNING OPENS YOU UP TO INJECTION ATTACKS)
 | 
			
		||||
 *  - **fullResult** {Boolean, default:false}, returns the full result document (document returned will differ by server version)
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Array|Object} docs
 | 
			
		||||
 * @param {Object} [options] optional options for insert command
 | 
			
		||||
 * @param {Function} [callback] optional callback for the function, must be provided when using a writeconcern
 | 
			
		||||
 * @return {Collection}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.insert = function() { return core.insert; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Removes documents specified by `selector` from the db.
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write
 | 
			
		||||
 *  - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option)
 | 
			
		||||
 *  - **fsync**, (Boolean, default:false) write waits for fsync before returning, from MongoDB 2.6 on, fsync cannot be combined with journal
 | 
			
		||||
 *  - **j**, (Boolean, default:false) write waits for journal sync before returning
 | 
			
		||||
 *  - **single** {Boolean, default:false}, removes the first document found.
 | 
			
		||||
 *  - **fullResult** {Boolean, default:false}, returns the full result document (document returned will differ by server version)
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Object} [selector] optional select, no selector is equivalent to removing all documents.
 | 
			
		||||
 * @param {Object} [options] additional options during remove.
 | 
			
		||||
 * @param {Function} [callback] must be provided if you performing a remove with a writeconcern
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.remove = function() { return core.remove; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Renames the collection.
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **dropTarget** {Boolean, default:false}, drop the target name collection if it previously exists.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {String} newName the new name of the collection.
 | 
			
		||||
 * @param {Object} [options] returns option results.
 | 
			
		||||
 * @param {Function} callback the callback accepting the result
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.rename = function() { return commands.rename; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Save a document. Simple full document replacement function. Not recommended for efficiency, use atomic
 | 
			
		||||
 * operators and update instead for more efficient operations.
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write
 | 
			
		||||
 *  - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option)
 | 
			
		||||
 *  - **fsync**, (Boolean, default:false) write waits for fsync before returning, from MongoDB 2.6 on, fsync cannot be combined with journal
 | 
			
		||||
 *  - **j**, (Boolean, default:false) write waits for journal sync before returning
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Object} [doc] the document to save
 | 
			
		||||
 * @param {Object} [options] additional options during remove.
 | 
			
		||||
 * @param {Function} [callback] must be provided if you performing an update with a writeconcern
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.save = function() { return core.save; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Updates documents.
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write
 | 
			
		||||
 *  - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option)
 | 
			
		||||
 *  - **fsync**, (Boolean, default:false) write waits for fsync before returning, from MongoDB 2.6 on, fsync cannot be combined with journal
 | 
			
		||||
 *  - **j**, (Boolean, default:false) write waits for journal sync before returning
 | 
			
		||||
 *  - **upsert** {Boolean, default:false}, perform an upsert operation.
 | 
			
		||||
 *  - **multi** {Boolean, default:false}, update all documents matching the selector.
 | 
			
		||||
 *  - **serializeFunctions** {Boolean, default:false}, serialize functions on the document.
 | 
			
		||||
 *  - **checkKeys** {Boolean, default:true}, allows for disabling of document key checking (WARNING OPENS YOU UP TO INJECTION ATTACKS)
 | 
			
		||||
 *  - **fullResult** {Boolean, default:false}, returns the full result document (document returned will differ by server version)
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Object} selector the query to select the document/documents to be updated
 | 
			
		||||
 * @param {Object} document the fields/vals to be updated, or in the case of an upsert operation, inserted.
 | 
			
		||||
 * @param {Object} [options] additional options during update.
 | 
			
		||||
 * @param {Function} [callback] must be provided if you performing an update with a writeconcern
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.update = function() { return core.update; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The distinct command returns returns a list of distinct values for the given key across a collection.
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **readPreference** {String}, the preferred read preference, require('mongodb').ReadPreference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
 | 
			
		||||
 *
 | 
			
		||||
 * @param {String} key key to run distinct against.
 | 
			
		||||
 * @param {Object} [query] option query to narrow the returned objects.
 | 
			
		||||
 * @param {Object} [options] additional options during update.
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from distinct or null if an error occured.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.distinct = function() { return commands.distinct; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Count number of matching documents in the db to a query.
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **skip** {Number}, The number of documents to skip for the count.
 | 
			
		||||
 *  - **limit** {Number}, The limit of documents to count.
 | 
			
		||||
 *  - **readPreference** {String}, the preferred read preference, require('mongodb').ReadPreference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Object} [query] query to filter by before performing count.
 | 
			
		||||
 * @param {Object} [options] additional options during count.
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the count method or null if an error occured.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.count = function() { return commands.count; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Drop the collection
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the drop method or null if an error occured.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.drop = function drop(callback) {
 | 
			
		||||
  this.db.dropCollection(this.collectionName, callback);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Find and update a document.
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write
 | 
			
		||||
 *  - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option)
 | 
			
		||||
 *  - **fsync**, (Boolean, default:false) write waits for fsync before returning, from MongoDB 2.6 on, fsync cannot be combined with journal
 | 
			
		||||
 *  - **j**, (Boolean, default:false) write waits for journal sync before returning
 | 
			
		||||
 *  - **remove** {Boolean, default:false}, set to true to remove the object before returning.
 | 
			
		||||
 *  - **upsert** {Boolean, default:false}, perform an upsert operation.
 | 
			
		||||
 *  - **new** {Boolean, default:false}, set to true if you want to return the modified object rather than the original. Ignored for remove.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Object} query query object to locate the object to modify
 | 
			
		||||
 * @param {Array}  sort - if multiple docs match, choose the first one in the specified sort order as the object to manipulate
 | 
			
		||||
 * @param {Object} doc - the fields/vals to be updated
 | 
			
		||||
 * @param {Object} [options] additional options during update.
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the findAndModify method or null if an error occured.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.findAndModify = function() { return core.findAndModify; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Find and remove a document
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write
 | 
			
		||||
 *  - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option)
 | 
			
		||||
 *  - **fsync**, (Boolean, default:false) write waits for fsync before returning, from MongoDB 2.6 on, fsync cannot be combined with journal
 | 
			
		||||
 *  - **j**, (Boolean, default:false) write waits for journal sync before returning
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Object} query query object to locate the object to modify
 | 
			
		||||
 * @param {Array}  sort - if multiple docs match, choose the first one in the specified sort order as the object to manipulate
 | 
			
		||||
 * @param {Object} [options] additional options during update.
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the findAndRemove method or null if an error occured.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.findAndRemove = function() { return core.findAndRemove; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Creates a cursor for a query that can be used to iterate over results from MongoDB
 | 
			
		||||
 *
 | 
			
		||||
 * Various argument possibilities
 | 
			
		||||
 *  - callback?
 | 
			
		||||
 *  - selector, callback?,
 | 
			
		||||
 *  - selector, fields, callback?
 | 
			
		||||
 *  - selector, options, callback?
 | 
			
		||||
 *  - selector, fields, options, callback?
 | 
			
		||||
 *  - selector, fields, skip, limit, callback?
 | 
			
		||||
 *  - selector, fields, skip, limit, timeout, callback?
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **limit** {Number, default:0}, sets the limit of documents returned in the query.
 | 
			
		||||
 *  - **sort** {Array | Object}, set to sort the documents coming back from the query. Array of indexes, [['a', 1]] etc.
 | 
			
		||||
 *  - **fields** {Object}, the fields to return in the query. Object of fields to include or exclude (not both), {'a':1}
 | 
			
		||||
 *  - **skip** {Number, default:0}, set to skip N documents ahead in your query (useful for pagination).
 | 
			
		||||
 *  - **hint** {Object}, tell the query to use specific indexes in the query. Object of indexes to use, {'_id':1}
 | 
			
		||||
 *  - **explain** {Boolean, default:false}, explain the query instead of returning the data.
 | 
			
		||||
 *  - **snapshot** {Boolean, default:false}, snapshot query.
 | 
			
		||||
 *  - **timeout** {Boolean, default:true}, specify if the cursor can timeout.
 | 
			
		||||
 *  - **tailable** {Boolean, default:false}, specify if the cursor is tailable.
 | 
			
		||||
 *  - **tailableRetryInterval** {Number, default:100}, specify the miliseconds between getMores on tailable cursor.
 | 
			
		||||
 *  - **numberOfRetries** {Number, default:5}, specify the number of times to retry the tailable cursor.
 | 
			
		||||
 *  - **awaitdata** {Boolean, default:false} allow the cursor to wait for data, only applicable for tailable cursor.
 | 
			
		||||
 *  - **oplogReplay** {Boolean, default:false} sets an internal flag, only applicable for tailable cursor.
 | 
			
		||||
 *  - **exhaust** {Boolean, default:false} have the server send all the documents at once as getMore packets, not recommended.
 | 
			
		||||
 *  - **batchSize** {Number, default:0}, set the batchSize for the getMoreCommand when iterating over the query results.
 | 
			
		||||
 *  - **returnKey** {Boolean, default:false}, only return the index key.
 | 
			
		||||
 *  - **maxScan** {Number}, Limit the number of items to scan.
 | 
			
		||||
 *  - **min** {Number}, Set index bounds.
 | 
			
		||||
 *  - **max** {Number}, Set index bounds.
 | 
			
		||||
 *  - **showDiskLoc** {Boolean, default:false}, Show disk location of results.
 | 
			
		||||
 *  - **comment** {String}, You can put a $comment field on a query to make looking in the profiler logs simpler.
 | 
			
		||||
 *  - **raw** {Boolean, default:false}, Return all BSON documents as Raw Buffer documents.
 | 
			
		||||
 *  - **readPreference** {String}, the preferred read preference, require('mongodb').ReadPreference ((ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
 | 
			
		||||
 *  - **numberOfRetries** {Number, default:5}, if using awaidata specifies the number of times to retry on timeout.
 | 
			
		||||
 *  - **partial** {Boolean, default:false}, specify if the cursor should return partial results when querying against a sharded system
 | 
			
		||||
 *  - **maxTimeMS** {Number}, number of miliseconds to wait before aborting the query.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Object|ObjectID} query query object to locate the object to modify
 | 
			
		||||
 * @param {Object} [options] additional options during update.
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the find method or null if an error occured.
 | 
			
		||||
 * @return {Cursor} returns a cursor to the query
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.find = function() { return query.find; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Finds a single document based on the query
 | 
			
		||||
 *
 | 
			
		||||
 * Various argument possibilities
 | 
			
		||||
 *  - callback?
 | 
			
		||||
 *  - selector, callback?,
 | 
			
		||||
 *  - selector, fields, callback?
 | 
			
		||||
 *  - selector, options, callback?
 | 
			
		||||
 *  - selector, fields, options, callback?
 | 
			
		||||
 *  - selector, fields, skip, limit, callback?
 | 
			
		||||
 *  - selector, fields, skip, limit, timeout, callback?
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **limit** {Number, default:0}, sets the limit of documents returned in the query.
 | 
			
		||||
 *  - **sort** {Array | Object}, set to sort the documents coming back from the query. Array of indexes, [['a', 1]] etc.
 | 
			
		||||
 *  - **fields** {Object}, the fields to return in the query. Object of fields to include or exclude (not both), {'a':1}
 | 
			
		||||
 *  - **skip** {Number, default:0}, set to skip N documents ahead in your query (useful for pagination).
 | 
			
		||||
 *  - **hint** {Object}, tell the query to use specific indexes in the query. Object of indexes to use, {'_id':1}
 | 
			
		||||
 *  - **explain** {Boolean, default:false}, explain the query instead of returning the data.
 | 
			
		||||
 *  - **snapshot** {Boolean, default:false}, snapshot query.
 | 
			
		||||
 *  - **timeout** {Boolean, default:false}, specify if the cursor can timeout.
 | 
			
		||||
 *  - **tailable** {Boolean, default:false}, specify if the cursor is tailable.
 | 
			
		||||
 *  - **batchSize** {Number, default:0}, set the batchSize for the getMoreCommand when iterating over the query results.
 | 
			
		||||
 *  - **returnKey** {Boolean, default:false}, only return the index key.
 | 
			
		||||
 *  - **maxScan** {Number}, Limit the number of items to scan.
 | 
			
		||||
 *  - **min** {Number}, Set index bounds.
 | 
			
		||||
 *  - **max** {Number}, Set index bounds.
 | 
			
		||||
 *  - **showDiskLoc** {Boolean, default:false}, Show disk location of results.
 | 
			
		||||
 *  - **comment** {String}, You can put a $comment field on a query to make looking in the profiler logs simpler.
 | 
			
		||||
 *  - **raw** {Boolean, default:false}, Return all BSON documents as Raw Buffer documents.
 | 
			
		||||
 *  - **readPreference** {String}, the preferred read preference, require('mongodb').ReadPreference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
 | 
			
		||||
 *  - **partial** {Boolean, default:false}, specify if the cursor should return partial results when querying against a sharded system
 | 
			
		||||
 *  - **maxTimeMS** {Number}, number of miliseconds to wait before aborting the query.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Object|ObjectID} query query object to locate the object to modify
 | 
			
		||||
 * @param {Object} [options] additional options during update.
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the findOne method or null if an error occured.
 | 
			
		||||
 * @return {Cursor} returns a cursor to the query
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.findOne = function() { return query.findOne; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Creates an index on the collection.
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write
 | 
			
		||||
 *  - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option)
 | 
			
		||||
 *  - **fsync**, (Boolean, default:false) write waits for fsync before returning, from MongoDB 2.6 on, fsync cannot be combined with journal
 | 
			
		||||
 *  - **j**, (Boolean, default:false) write waits for journal sync before returning
 | 
			
		||||
 *  - **unique** {Boolean, default:false}, creates an unique index.
 | 
			
		||||
 *  - **sparse** {Boolean, default:false}, creates a sparse index.
 | 
			
		||||
 *  - **background** {Boolean, default:false}, creates the index in the background, yielding whenever possible.
 | 
			
		||||
 *  - **min** {Number}, for geospatial indexes set the lower bound for the co-ordinates.
 | 
			
		||||
 *  - **max** {Number}, for geospatial indexes set the high bound for the co-ordinates.
 | 
			
		||||
 *  - **v** {Number}, specify the format version of the indexes.
 | 
			
		||||
 *  - **expireAfterSeconds** {Number}, allows you to expire data on indexes applied to a data (MongoDB 2.2 or higher)
 | 
			
		||||
 *  - **name** {String}, override the autogenerated index name (useful if the resulting name is larger than 128 bytes)
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Object} fieldOrSpec fieldOrSpec that defines the index.
 | 
			
		||||
 * @param {Object} [options] additional options during update.
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the createIndex method or null if an error occured.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.createIndex = function() { return index.createIndex; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Ensures that an index exists, if it does not it creates it
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write
 | 
			
		||||
 *  - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option)
 | 
			
		||||
 *  - **fsync**, (Boolean, default:false) write waits for fsync before returning, from MongoDB 2.6 on, fsync cannot be combined with journal
 | 
			
		||||
 *  - **j**, (Boolean, default:false) write waits for journal sync before returning
 | 
			
		||||
 *  - **unique** {Boolean, default:false}, creates an unique index.
 | 
			
		||||
 *  - **sparse** {Boolean, default:false}, creates a sparse index.
 | 
			
		||||
 *  - **background** {Boolean, default:false}, creates the index in the background, yielding whenever possible.
 | 
			
		||||
 *  - **min** {Number}, for geospatial indexes set the lower bound for the co-ordinates.
 | 
			
		||||
 *  - **max** {Number}, for geospatial indexes set the high bound for the co-ordinates.
 | 
			
		||||
 *  - **v** {Number}, specify the format version of the indexes.
 | 
			
		||||
 *  - **expireAfterSeconds** {Number}, allows you to expire data on indexes applied to a data (MongoDB 2.2 or higher)
 | 
			
		||||
 *  - **name** {String}, override the autogenerated index name (useful if the resulting name is larger than 128 bytes)
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Object} fieldOrSpec fieldOrSpec that defines the index.
 | 
			
		||||
 * @param {Object} [options] additional options during update.
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the ensureIndex method or null if an error occured.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.ensureIndex = function() { return index.ensureIndex; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the list of all indexes information for the collection.
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **batchSize**, {Number, 0} The batchSize for the returned command cursor or if pre 2.8 the systems batch collection
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Object} [options] additional options during update.
 | 
			
		||||
 * @return {Cursor}
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.listIndexes = function() { return index.listIndexes; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Retrieves this collections index info.
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **full** {Boolean, default:false}, returns the full raw index information.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Object} [options] additional options during update.
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the indexInformation method or null if an error occured.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.indexInformation = function() { return index.indexInformation; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Drops an index from this collection.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {String} name
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the dropIndex method or null if an error occured.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.dropIndex = function dropIndex (name, options, callback) {
 | 
			
		||||
  if(typeof options == 'function') {
 | 
			
		||||
    callback = options;
 | 
			
		||||
    options = {};
 | 
			
		||||
  }  
 | 
			
		||||
  // Execute dropIndex command
 | 
			
		||||
  this.db.dropIndex(this.collectionName, name, options, callback);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Drops all indexes from this collection.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the dropAllIndexes method or null if an error occured.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.dropAllIndexes = function() { return index.dropAllIndexes; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Drops all indexes from this collection.
 | 
			
		||||
 *
 | 
			
		||||
 * @deprecated
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the dropIndexes method or null if an error occured.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.dropIndexes = function() { return Collection.prototype.dropAllIndexes; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Reindex all indexes on the collection
 | 
			
		||||
 * Warning: reIndex is a blocking operation (indexes are rebuilt in the foreground) and will be slow for large collections.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the reIndex method or null if an error occured.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
**/
 | 
			
		||||
Collection.prototype.reIndex = function(options, callback) {
 | 
			
		||||
  if(typeof options == 'function') {
 | 
			
		||||
    callback = options;
 | 
			
		||||
    options = {};
 | 
			
		||||
  }  
 | 
			
		||||
  // Execute reIndex
 | 
			
		||||
  this.db.reIndex(this.collectionName, options, callback);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Run Map Reduce across a collection. Be aware that the inline option for out will return an array of results not a collection.
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **out** {Object}, sets the output target for the map reduce job. *{inline:1} | {replace:'collectionName'} | {merge:'collectionName'} | {reduce:'collectionName'}*
 | 
			
		||||
 *  - **query** {Object}, query filter object.
 | 
			
		||||
 *  - **sort** {Object}, sorts the input objects using this key. Useful for optimization, like sorting by the emit key for fewer reduces.
 | 
			
		||||
 *  - **limit** {Number}, number of objects to return from collection.
 | 
			
		||||
 *  - **keeptemp** {Boolean, default:false}, keep temporary data.
 | 
			
		||||
 *  - **finalize** {Function | String}, finalize function.
 | 
			
		||||
 *  - **scope** {Object}, can pass in variables that can be access from map/reduce/finalize.
 | 
			
		||||
 *  - **jsMode** {Boolean, default:false}, it is possible to make the execution stay in JS. Provided in MongoDB > 2.0.X.
 | 
			
		||||
 *  - **verbose** {Boolean, default:false}, provide statistics on job execution time.
 | 
			
		||||
 *  - **readPreference** {String, only for inline results}, the preferred read preference, require('mongodb').ReadPreference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Function|String} map the mapping function.
 | 
			
		||||
 * @param {Function|String} reduce the reduce function.
 | 
			
		||||
 * @param {Objects} [options] options for the map reduce job.
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the mapReduce method or null if an error occured.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.mapReduce = function() { return aggregation.mapReduce; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Run a group command across a collection
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **readPreference** {String}, the preferred read preference, require('mongodb').ReadPreference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Object|Array|Function|Code} keys an object, array or function expressing the keys to group by.
 | 
			
		||||
 * @param {Object} condition an optional condition that must be true for a row to be considered.
 | 
			
		||||
 * @param {Object} initial initial value of the aggregation counter object.
 | 
			
		||||
 * @param {Function|Code} reduce the reduce function aggregates (reduces) the objects iterated
 | 
			
		||||
 * @param {Function|Code} finalize an optional function to be run on each item in the result set just before the item is returned.
 | 
			
		||||
 * @param {Boolean} command specify if you wish to run using the internal group command or using eval, default is true.
 | 
			
		||||
 * @param {Object} [options] additional options during update.
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the group method or null if an error occured.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.group = function() { return aggregation.group; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns the options of the collection.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the options method or null if an error occured.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.options = function() { return commands.options; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns if the collection is a capped collection
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the isCapped method or null if an error occured.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.isCapped = function() { return commands.isCapped; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks if one or more indexes exist on the collection
 | 
			
		||||
 *
 | 
			
		||||
 * @param {String|Array} indexNames check if one or more indexes exist on the collection.
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the indexExists method or null if an error occured.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.indexExists = function() { return index.indexExists; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Execute the geoNear command to search for items in the collection
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **num** {Number}, max number of results to return.
 | 
			
		||||
 *  - **minDistance** {Number}, include results starting at minDistance from a point (2.6 or higher)
 | 
			
		||||
 *  - **maxDistance** {Number}, include results up to maxDistance from the point.
 | 
			
		||||
 *  - **distanceMultiplier** {Number}, include a value to multiply the distances with allowing for range conversions.
 | 
			
		||||
 *  - **query** {Object}, filter the results by a query.
 | 
			
		||||
 *  - **spherical** {Boolean, default:false}, perform query using a spherical model.
 | 
			
		||||
 *  - **uniqueDocs** {Boolean, default:false}, the closest location in a document to the center of the search region will always be returned MongoDB > 2.X.
 | 
			
		||||
 *  - **includeLocs** {Boolean, default:false}, include the location data fields in the top level of the results MongoDB > 2.X.
 | 
			
		||||
 *  - **readPreference** {String}, the preferred read preference, require('mongodb').ReadPreference ((ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Number} x point to search on the x axis, ensure the indexes are ordered in the same order.
 | 
			
		||||
 * @param {Number} y point to search on the y axis, ensure the indexes are ordered in the same order.
 | 
			
		||||
 * @param {Objects} [options] options for the map reduce job.
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the geoNear method or null if an error occured.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.geoNear = function() { return geo.geoNear; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Execute a geo search using a geo haystack index on a collection.
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **maxDistance** {Number}, include results up to maxDistance from the point.
 | 
			
		||||
 *  - **search** {Object}, filter the results by a query.
 | 
			
		||||
 *  - **limit** {Number}, max number of results to return.
 | 
			
		||||
 *  - **readPreference** {String}, the preferred read preference, require('mongodb').ReadPreference ((ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Number} x point to search on the x axis, ensure the indexes are ordered in the same order.
 | 
			
		||||
 * @param {Number} y point to search on the y axis, ensure the indexes are ordered in the same order.
 | 
			
		||||
 * @param {Objects} [options] options for the map reduce job.
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the geoHaystackSearch method or null if an error occured.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.geoHaystackSearch = function() { return geo.geoHaystackSearch; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Retrieve all the indexes on the collection.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the indexes method or null if an error occured.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.indexes = function indexes(callback) {
 | 
			
		||||
  this.db.indexInformation(this.collectionName, {full:true}, callback);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Execute an aggregation framework pipeline against the collection, needs MongoDB >= 2.2
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **readPreference** {String}, the preferred read preference, require('mongodb').ReadPreference ((ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
 | 
			
		||||
 *  - **cursor** {Object}, return the query as cursor, on 2.6 > it returns as a real cursor on pre 2.6 it returns as an emulated cursor.
 | 
			
		||||
 *  - **cursor.batchSize** {Number}, the batchSize for the cursor
 | 
			
		||||
 *  - **out** {String}, the collection name to where to write the results from the aggregation (MongoDB 2.6 or higher). Warning any existing collection will be overwritten.
 | 
			
		||||
 *  - **explain** {Boolean, default:false}, explain returns the aggregation execution plan (requires mongodb 2.6 >).
 | 
			
		||||
 *  - **allowDiskUse** {Boolean, default:false}, allowDiskUse lets the server know if it can use disk to store temporary results for the aggregation (requires mongodb 2.6 >).
 | 
			
		||||
 *  - **maxTimeMS** {Number}, maxTimeMS the maxTimeMS operator specifies a cumulative time limit in milliseconds for processing operations on the cursor. MongoDB interrupts the operation at the earliest following interrupt point.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Array} array containing all the aggregation framework commands for the execution.
 | 
			
		||||
 * @param {Object} [options] additional options during update.
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the aggregate method or null if an error occured.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.aggregate = function() { return aggregation.aggregate; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get all the collection statistics.
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **scale** {Number}, divide the returned sizes by scale value.
 | 
			
		||||
 *  - **readPreference** {String}, the preferred read preference, require('mongodb').ReadPreference ((ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Objects} [options] options for the stats command.
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the stats method or null if an error occured.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.stats = function() { return commands.stats; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Initiate a Out of order batch write operation. All operations will be buffered into insert/update/remove commands executed out of order.
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write
 | 
			
		||||
 *  - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option)
 | 
			
		||||
 *  - **fsync**, (Boolean, default:false) write waits for fsync before returning, from MongoDB 2.6 on, fsync cannot be combined with journal
 | 
			
		||||
 *  - **j**, (Boolean, default:false) write waits for journal sync before returning
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Objects} [options] options for the initializeUnorderedBatch 
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. The second argument will be a UnorderedBulkOperation object.
 | 
			
		||||
 * @return {UnorderedBulkOperation}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.initializeUnorderedBulkOp = function() { return unordered.initializeUnorderedBulkOp; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Initiate an In order bulk write operation, operations will be serially executed in the order they are added, creating a new operation for each switch in types.
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write
 | 
			
		||||
 *  - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option)
 | 
			
		||||
 *  - **fsync**, (Boolean, default:false) write waits for fsync before returning, from MongoDB 2.6 on, fsync cannot be combined with journal
 | 
			
		||||
 *  - **j**, (Boolean, default:false) write waits for journal sync before returning
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Objects} [options] options for the initializeOrderedBulkOp 
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. The second argument will be a OrderedBulkOperation object.
 | 
			
		||||
 * @return {OrderedBulkOperation}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.initializeOrderedBulkOp = function() { return ordered.initializeOrderedBulkOp; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Return N number of parallel cursors for a collection allowing parallel reading of entire collection. There are
 | 
			
		||||
 * no ordering guarantees for returned results.
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
 | 
			
		||||
 *  - **batchSize** {Number, default:0}, set the batchSize for the getMoreCommand when iterating over the query results.
 | 
			
		||||
 *  - **numCursors**, {Number, 1} the maximum number of parallel command cursors to return (the number of returned cursors will be in the range 1:numCursors)
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Objects} [options] options for the initializeOrderedBulkOp 
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. The second argument will be an array of CommandCursor instances.
 | 
			
		||||
 * @return {OrderedBulkOperation}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Collection.prototype.parallelCollectionScan = function() { return query.parallelCollectionScan; }();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Object.defineProperty(Collection.prototype, "hint", {
 | 
			
		||||
    enumerable: true
 | 
			
		||||
  , get: function () {
 | 
			
		||||
      return this.internalHint;
 | 
			
		||||
    }
 | 
			
		||||
  , set: function (v) {
 | 
			
		||||
      this.internalHint = shared.normalizeHintField(v);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Expose.
 | 
			
		||||
 */
 | 
			
		||||
exports.Collection = Collection;
 | 
			
		||||
							
								
								
									
										325
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/collection/aggregation.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										325
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/collection/aggregation.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,325 @@
 | 
			
		||||
var shared = require('./shared')
 | 
			
		||||
  , utils = require('../utils')
 | 
			
		||||
  , AggregationCursor = require('../aggregation_cursor').AggregationCursor
 | 
			
		||||
  , Code = require('bson').Code  
 | 
			
		||||
  , DbCommand = require('../commands/db_command').DbCommand;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Functions that are passed as scope args must
 | 
			
		||||
 * be converted to Code instances.
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
function processScope (scope) {
 | 
			
		||||
  if (!utils.isObject(scope)) {
 | 
			
		||||
    return scope;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var keys = Object.keys(scope);
 | 
			
		||||
  var i = keys.length;
 | 
			
		||||
  var key;
 | 
			
		||||
  var new_scope = {};
 | 
			
		||||
 | 
			
		||||
  while (i--) {
 | 
			
		||||
    key = keys[i];
 | 
			
		||||
    if ('function' == typeof scope[key]) {
 | 
			
		||||
      new_scope[key] = new Code(String(scope[key]));
 | 
			
		||||
    } else {
 | 
			
		||||
      new_scope[key] = processScope(scope[key]);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return new_scope;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var pipe = function() {
 | 
			
		||||
  return new AggregationCursor(this, this.serverCapabilities);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var mapReduce = function mapReduce (map, reduce, options, callback) {
 | 
			
		||||
  if ('function' === typeof options) callback = options, options = {};
 | 
			
		||||
  // Out must allways be defined (make sure we don't break weirdly on pre 1.8+ servers)
 | 
			
		||||
  if(null == options.out) {
 | 
			
		||||
    throw new Error("the out option parameter must be defined, see mongodb docs for possible values");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if ('function' === typeof map) {
 | 
			
		||||
    map = map.toString();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if ('function' === typeof reduce) {
 | 
			
		||||
    reduce = reduce.toString();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if ('function' === typeof options.finalize) {
 | 
			
		||||
    options.finalize = options.finalize.toString();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var mapCommandHash = {
 | 
			
		||||
      mapreduce: this.collectionName
 | 
			
		||||
    , map: map
 | 
			
		||||
    , reduce: reduce
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // Add any other options passed in
 | 
			
		||||
  for (var name in options) {
 | 
			
		||||
    if ('scope' == name) {
 | 
			
		||||
      mapCommandHash[name] = processScope(options[name]);
 | 
			
		||||
    } else {
 | 
			
		||||
      mapCommandHash[name] = options[name];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Set read preference if we set one
 | 
			
		||||
  var readPreference = shared._getReadConcern(this, options);
 | 
			
		||||
 | 
			
		||||
  // If we have a read preference and inline is not set as output fail hard
 | 
			
		||||
  if((readPreference != false && readPreference != 'primary') 
 | 
			
		||||
    && options['out'] && (options['out'].inline != 1 && options['out'] != 'inline')) {
 | 
			
		||||
      readPreference = 'primary';    
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // self
 | 
			
		||||
  var self = this;
 | 
			
		||||
  var cmd = DbCommand.createDbCommand(this.db, mapCommandHash);
 | 
			
		||||
 | 
			
		||||
  this.db._executeQueryCommand(cmd, {readPreference:readPreference}, function (err, result) {
 | 
			
		||||
    if(err) return callback(err);
 | 
			
		||||
    if(!result || !result.documents || result.documents.length == 0)
 | 
			
		||||
      return callback(Error("command failed to return results"), null)
 | 
			
		||||
 | 
			
		||||
    // Check if we have an error
 | 
			
		||||
    if(1 != result.documents[0].ok || result.documents[0].err || result.documents[0].errmsg) {
 | 
			
		||||
      return callback(utils.toError(result.documents[0]));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Create statistics value
 | 
			
		||||
    var stats = {};
 | 
			
		||||
    if(result.documents[0].timeMillis) stats['processtime'] = result.documents[0].timeMillis;
 | 
			
		||||
    if(result.documents[0].counts) stats['counts'] = result.documents[0].counts;
 | 
			
		||||
    if(result.documents[0].timing) stats['timing'] = result.documents[0].timing;
 | 
			
		||||
 | 
			
		||||
    // invoked with inline?
 | 
			
		||||
    if(result.documents[0].results) {
 | 
			
		||||
      // If we wish for no verbosity
 | 
			
		||||
      if(options['verbose'] == null || !options['verbose']) {
 | 
			
		||||
        return callback(null, result.documents[0].results);
 | 
			
		||||
      }
 | 
			
		||||
      return callback(null, result.documents[0].results, stats);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // The returned collection
 | 
			
		||||
    var collection = null;
 | 
			
		||||
 | 
			
		||||
    // If we have an object it's a different db
 | 
			
		||||
    if(result.documents[0].result != null && typeof result.documents[0].result == 'object') {
 | 
			
		||||
      var doc = result.documents[0].result;
 | 
			
		||||
      collection = self.db.db(doc.db).collection(doc.collection);
 | 
			
		||||
    } else {
 | 
			
		||||
      // Create a collection object that wraps the result collection
 | 
			
		||||
      collection = self.db.collection(result.documents[0].result)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If we wish for no verbosity
 | 
			
		||||
    if(options['verbose'] == null || !options['verbose']) {
 | 
			
		||||
      return callback(err, collection);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Return stats as third set of values
 | 
			
		||||
    callback(err, collection, stats);
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Group function helper
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
var groupFunction = function () {
 | 
			
		||||
  var c = db[ns].find(condition);
 | 
			
		||||
  var map = new Map();
 | 
			
		||||
  var reduce_function = reduce;
 | 
			
		||||
 | 
			
		||||
  while (c.hasNext()) {
 | 
			
		||||
    var obj = c.next();
 | 
			
		||||
    var key = {};
 | 
			
		||||
 | 
			
		||||
    for (var i = 0, len = keys.length; i < len; ++i) {
 | 
			
		||||
      var k = keys[i];
 | 
			
		||||
      key[k] = obj[k];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var aggObj = map.get(key);
 | 
			
		||||
 | 
			
		||||
    if (aggObj == null) {
 | 
			
		||||
      var newObj = Object.extend({}, key);
 | 
			
		||||
      aggObj = Object.extend(newObj, initial);
 | 
			
		||||
      map.put(key, aggObj);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    reduce_function(obj, aggObj);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return { "result": map.values() };
 | 
			
		||||
}.toString();
 | 
			
		||||
 | 
			
		||||
var group = function group(keys, condition, initial, reduce, finalize, command, options, callback) {
 | 
			
		||||
  var args = Array.prototype.slice.call(arguments, 3);
 | 
			
		||||
  callback = args.pop();
 | 
			
		||||
  // Fetch all commands
 | 
			
		||||
  reduce = args.length ? args.shift() : null;
 | 
			
		||||
  finalize = args.length ? args.shift() : null;
 | 
			
		||||
  command = args.length ? args.shift() : null;
 | 
			
		||||
  options = args.length ? args.shift() || {} : {};
 | 
			
		||||
 | 
			
		||||
  // Make sure we are backward compatible
 | 
			
		||||
  if(!(typeof finalize == 'function')) {
 | 
			
		||||
    command = finalize;
 | 
			
		||||
    finalize = null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (!Array.isArray(keys) && keys instanceof Object && typeof(keys) !== 'function' && !(keys instanceof Code)) {
 | 
			
		||||
    keys = Object.keys(keys);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(typeof reduce === 'function') {
 | 
			
		||||
    reduce = reduce.toString();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(typeof finalize === 'function') {
 | 
			
		||||
    finalize = finalize.toString();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Set up the command as default
 | 
			
		||||
  command = command == null ? true : command;
 | 
			
		||||
 | 
			
		||||
  // Execute using the command
 | 
			
		||||
  if(command) {
 | 
			
		||||
    var reduceFunction = reduce instanceof Code
 | 
			
		||||
        ? reduce
 | 
			
		||||
        : new Code(reduce);
 | 
			
		||||
 | 
			
		||||
    var selector = {
 | 
			
		||||
      group: {
 | 
			
		||||
          'ns': this.collectionName
 | 
			
		||||
        , '$reduce': reduceFunction
 | 
			
		||||
        , 'cond': condition
 | 
			
		||||
        , 'initial': initial
 | 
			
		||||
        , 'out': "inline"
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // if finalize is defined
 | 
			
		||||
    if(finalize != null) selector.group['finalize'] = finalize;
 | 
			
		||||
    // Set up group selector
 | 
			
		||||
    if ('function' === typeof keys || keys instanceof Code) {
 | 
			
		||||
      selector.group.$keyf = keys instanceof Code
 | 
			
		||||
        ? keys
 | 
			
		||||
        : new Code(keys);
 | 
			
		||||
    } else {
 | 
			
		||||
      var hash = {};
 | 
			
		||||
      keys.forEach(function (key) {
 | 
			
		||||
        hash[key] = 1;
 | 
			
		||||
      });
 | 
			
		||||
      selector.group.key = hash;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Set read preference if we set one
 | 
			
		||||
    var readPreference = shared._getReadConcern(this, options);
 | 
			
		||||
    // Execute command
 | 
			
		||||
    this.db.command(selector, {readPreference: readPreference}, function(err, result) {
 | 
			
		||||
      if(err) return callback(err, null);
 | 
			
		||||
      callback(null, result.retval);
 | 
			
		||||
    });
 | 
			
		||||
  } else {
 | 
			
		||||
    // Create execution scope
 | 
			
		||||
    var scope = reduce != null && reduce instanceof Code
 | 
			
		||||
      ? reduce.scope
 | 
			
		||||
      : {};
 | 
			
		||||
 | 
			
		||||
    scope.ns = this.collectionName;
 | 
			
		||||
    scope.keys = keys;
 | 
			
		||||
    scope.condition = condition;
 | 
			
		||||
    scope.initial = initial;
 | 
			
		||||
 | 
			
		||||
    // Pass in the function text to execute within mongodb.
 | 
			
		||||
    var groupfn = groupFunction.replace(/ reduce;/, reduce.toString() + ';');
 | 
			
		||||
 | 
			
		||||
    this.db.eval(new Code(groupfn, scope), function (err, results) {
 | 
			
		||||
      if (err) return callback(err, null);
 | 
			
		||||
      callback(null, results.result || results);
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var aggregate = function(pipeline, options, callback) {
 | 
			
		||||
  var args = Array.prototype.slice.call(arguments, 0);
 | 
			
		||||
  callback = args.pop();
 | 
			
		||||
  var self = this;
 | 
			
		||||
 | 
			
		||||
  // If we have any of the supported options in the options object
 | 
			
		||||
  var opts = args[args.length - 1] || {};
 | 
			
		||||
  options = opts.readPreference 
 | 
			
		||||
    || opts.explain 
 | 
			
		||||
    || opts.cursor 
 | 
			
		||||
    || opts.out
 | 
			
		||||
    || opts.maxTimeMS
 | 
			
		||||
    || opts.allowDiskUse ? args.pop() : {}
 | 
			
		||||
 | 
			
		||||
  // If the callback is the option (as for cursor override it)
 | 
			
		||||
  if(typeof callback == 'object' && callback != null) options = callback;
 | 
			
		||||
 | 
			
		||||
  // Convert operations to an array
 | 
			
		||||
  if(!Array.isArray(args[0])) {
 | 
			
		||||
    pipeline = [];
 | 
			
		||||
    // Push all the operations to the pipeline
 | 
			
		||||
    for(var i = 0; i < args.length; i++) pipeline.push(args[i]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Is the user requesting a cursor
 | 
			
		||||
  if(options.cursor != null && options.out == null) {
 | 
			
		||||
    if(typeof options.cursor != 'object') throw utils.toError('cursor options must be an object');
 | 
			
		||||
    // Set the aggregation cursor options
 | 
			
		||||
    var agg_cursor_options = options.cursor;
 | 
			
		||||
    agg_cursor_options.pipe = pipeline;
 | 
			
		||||
    agg_cursor_options.allowDiskUse = options.allowDiskUse == null ? false : options.allowDiskUse;
 | 
			
		||||
    // Set the maxTimeMS if passed in
 | 
			
		||||
    if(typeof options.maxTimeMS == 'number') agg_cursor_options.maxTimeMS = options.maxTimeMS;
 | 
			
		||||
    // Return the aggregation cursor
 | 
			
		||||
    return new AggregationCursor(this, this.serverCapabilities, agg_cursor_options);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // If out was specified
 | 
			
		||||
  if(typeof options.out == 'string') {
 | 
			
		||||
    pipeline.push({$out: options.out});
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Build the command
 | 
			
		||||
  var command = { aggregate : this.collectionName, pipeline : pipeline};
 | 
			
		||||
  // If we have allowDiskUse defined
 | 
			
		||||
  if(options.allowDiskUse) command.allowDiskUse = options.allowDiskUse;
 | 
			
		||||
  // Set the maxTimeMS if passed in
 | 
			
		||||
  if(typeof options.maxTimeMS == 'number') command.maxTimeMS = options.maxTimeMS;
 | 
			
		||||
 | 
			
		||||
  // Ensure we have the right read preference inheritance
 | 
			
		||||
  options.readPreference = shared._getReadConcern(this, options);
 | 
			
		||||
  // If explain has been specified add it
 | 
			
		||||
  if(options.explain) command.explain = options.explain;
 | 
			
		||||
  // Execute the command
 | 
			
		||||
  this.db.command(command, options, function(err, result) {
 | 
			
		||||
    if(err) {
 | 
			
		||||
      callback(err);
 | 
			
		||||
    } else if(result['err'] || result['errmsg']) {
 | 
			
		||||
      callback(utils.toError(result));
 | 
			
		||||
    } else if(typeof result == 'object' && result['serverPipeline']) {
 | 
			
		||||
      callback(null, result['serverPipeline']);
 | 
			
		||||
    } else if(typeof result == 'object' && result['stages']) {
 | 
			
		||||
      callback(null, result['stages']);
 | 
			
		||||
    } else {
 | 
			
		||||
      callback(null, result.result);
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.mapReduce = mapReduce;
 | 
			
		||||
exports.group = group;
 | 
			
		||||
exports.aggregate = aggregate;
 | 
			
		||||
exports.pipe = pipe;
 | 
			
		||||
							
								
								
									
										440
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/collection/batch/common.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										440
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/collection/batch/common.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,440 @@
 | 
			
		||||
var utils = require('../../utils');
 | 
			
		||||
 | 
			
		||||
// Error codes
 | 
			
		||||
var UNKNOWN_ERROR = 8;
 | 
			
		||||
var INVALID_BSON_ERROR = 22;
 | 
			
		||||
var WRITE_CONCERN_ERROR = 64;
 | 
			
		||||
var MULTIPLE_ERROR = 65;
 | 
			
		||||
 | 
			
		||||
// Insert types
 | 
			
		||||
var INSERT = 1;
 | 
			
		||||
var UPDATE = 2;
 | 
			
		||||
var REMOVE = 3
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Helper function to define properties
 | 
			
		||||
 */
 | 
			
		||||
var defineReadOnlyProperty = function(self, name, value) {
 | 
			
		||||
  Object.defineProperty(self, name, {
 | 
			
		||||
      enumerable: true
 | 
			
		||||
    , get: function() {
 | 
			
		||||
      return value;
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Keeps the state of a unordered batch so we can rewrite the results
 | 
			
		||||
 * correctly after command execution
 | 
			
		||||
 */
 | 
			
		||||
var Batch = function(batchType, originalZeroIndex) {  
 | 
			
		||||
  this.originalZeroIndex = originalZeroIndex;
 | 
			
		||||
  this.currentIndex = 0;
 | 
			
		||||
  this.originalIndexes = [];
 | 
			
		||||
  this.batchType = batchType;
 | 
			
		||||
  this.operations = [];
 | 
			
		||||
  this.size = 0;
 | 
			
		||||
  this.sizeBytes = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Wraps a legacy operation so we can correctly rewrite it's error
 | 
			
		||||
 */
 | 
			
		||||
var LegacyOp = function(batchType, operation, index) {
 | 
			
		||||
  this.batchType = batchType;
 | 
			
		||||
  this.index = index;
 | 
			
		||||
  this.operation = operation;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create a new BatchWriteResult instance (INTERNAL TYPE, do not instantiate directly)
 | 
			
		||||
 *
 | 
			
		||||
 * @class Represents a BatchWriteResult
 | 
			
		||||
 * @property **ok** {boolean} did bulk operation correctly execute
 | 
			
		||||
 * @property **nInserted** {number} number of inserted documents
 | 
			
		||||
 * @property **nUpdated** {number} number of documents updated logically
 | 
			
		||||
 * @property **nUpserted** {number} number of upserted documents
 | 
			
		||||
 * @property **nModified** {number} number of documents updated physically on disk
 | 
			
		||||
 * @property **nRemoved** {number} number of removed documents
 | 
			
		||||
 * @param {Object} batchResult internal data structure with results.
 | 
			
		||||
 * @return {BatchWriteResult} a BatchWriteResult instance
 | 
			
		||||
 */
 | 
			
		||||
var BatchWriteResult = function(bulkResult) {
 | 
			
		||||
  defineReadOnlyProperty(this, "ok", bulkResult.ok);
 | 
			
		||||
  defineReadOnlyProperty(this, "nInserted", bulkResult.nInserted);
 | 
			
		||||
  defineReadOnlyProperty(this, "nUpserted", bulkResult.nUpserted);
 | 
			
		||||
  defineReadOnlyProperty(this, "nMatched", bulkResult.nMatched);
 | 
			
		||||
  defineReadOnlyProperty(this, "nModified", bulkResult.nModified);
 | 
			
		||||
  defineReadOnlyProperty(this, "nRemoved", bulkResult.nRemoved);
 | 
			
		||||
  
 | 
			
		||||
  /**
 | 
			
		||||
   * Return an array of upserted ids
 | 
			
		||||
   *
 | 
			
		||||
   * @return {Array}
 | 
			
		||||
   * @api public
 | 
			
		||||
   */
 | 
			
		||||
  this.getUpsertedIds = function() {
 | 
			
		||||
    return bulkResult.upserted;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Return the upserted id at position x
 | 
			
		||||
   *
 | 
			
		||||
   * @param {Number} index the number of the upserted id to return, returns undefined if no result for passed in index
 | 
			
		||||
   * @return {Array}
 | 
			
		||||
   * @api public
 | 
			
		||||
   */
 | 
			
		||||
  this.getUpsertedIdAt = function(index) {
 | 
			
		||||
    return bulkResult.upserted[index]; 
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Return raw internal result
 | 
			
		||||
   *
 | 
			
		||||
   * @return {Object}
 | 
			
		||||
   * @api public
 | 
			
		||||
   */
 | 
			
		||||
  this.getRawResponse = function() {
 | 
			
		||||
    return bulkResult;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns true if the bulk operation contains a write error
 | 
			
		||||
   *
 | 
			
		||||
   * @return {Boolean}
 | 
			
		||||
   * @api public
 | 
			
		||||
   */
 | 
			
		||||
  this.hasWriteErrors = function() {
 | 
			
		||||
    return bulkResult.writeErrors.length > 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns the number of write errors off the bulk operation
 | 
			
		||||
   *
 | 
			
		||||
   * @return {Number}
 | 
			
		||||
   * @api public
 | 
			
		||||
   */
 | 
			
		||||
  this.getWriteErrorCount = function() {
 | 
			
		||||
    return bulkResult.writeErrors.length;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Returns a specific write error object
 | 
			
		||||
   *
 | 
			
		||||
   * @return {WriteError}
 | 
			
		||||
   * @api public
 | 
			
		||||
   */
 | 
			
		||||
  this.getWriteErrorAt = function(index) {
 | 
			
		||||
    if(index < bulkResult.writeErrors.length) {
 | 
			
		||||
      return bulkResult.writeErrors[index];
 | 
			
		||||
    }
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Retrieve all write errors
 | 
			
		||||
   *
 | 
			
		||||
   * @return {Array}
 | 
			
		||||
   * @api public
 | 
			
		||||
   */
 | 
			
		||||
  this.getWriteErrors = function() {
 | 
			
		||||
    return bulkResult.writeErrors;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Retrieve lastOp if available
 | 
			
		||||
   *
 | 
			
		||||
   * @return {Array}
 | 
			
		||||
   * @api public
 | 
			
		||||
   */
 | 
			
		||||
  this.getLastOp = function() {
 | 
			
		||||
    return bulkResult.lastOp;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Retrieve the write concern error if any
 | 
			
		||||
   *
 | 
			
		||||
   * @return {WriteConcernError}
 | 
			
		||||
   * @api public
 | 
			
		||||
   */
 | 
			
		||||
  this.getWriteConcernError = function() {
 | 
			
		||||
    if(bulkResult.writeConcernErrors.length == 0) {
 | 
			
		||||
      return null;
 | 
			
		||||
    } else if(bulkResult.writeConcernErrors.length == 1) {
 | 
			
		||||
      // Return the error
 | 
			
		||||
      return bulkResult.writeConcernErrors[0];
 | 
			
		||||
    } else {
 | 
			
		||||
 | 
			
		||||
      // Combine the errors
 | 
			
		||||
      var errmsg = "";
 | 
			
		||||
      for(var i = 0; i < bulkResult.writeConcernErrors.length; i++) {
 | 
			
		||||
        var err = bulkResult.writeConcernErrors[i];
 | 
			
		||||
        errmsg = errmsg + err.errmsg;
 | 
			
		||||
        
 | 
			
		||||
        // TODO: Something better
 | 
			
		||||
        if(i == 0) errmsg = errmsg + " and ";
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return new WriteConcernError({ errmsg : errmsg, code : WRITE_CONCERN_ERROR });
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.toJSON = function() {
 | 
			
		||||
    return bulkResult;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.toString = function() {
 | 
			
		||||
    return "BatchWriteResult(" + this.toJSON(bulkResult) + ")";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.isOk = function() {
 | 
			
		||||
    return bulkResult.ok == 1;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Wraps a write concern error
 | 
			
		||||
 */
 | 
			
		||||
var WriteConcernError = function(err) {
 | 
			
		||||
  if(!(this instanceof WriteConcernError)) return new WriteConcernError(err);
 | 
			
		||||
 | 
			
		||||
  // Define properties
 | 
			
		||||
  defineReadOnlyProperty(this, "code", err.code);
 | 
			
		||||
  defineReadOnlyProperty(this, "errmsg", err.errmsg);
 | 
			
		||||
 | 
			
		||||
  this.toJSON = function() {
 | 
			
		||||
    return {code: err.code, errmsg: err.errmsg};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.toString = function() {
 | 
			
		||||
    return "WriteConcernError(" + err.errmsg + ")";
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Wraps the error
 | 
			
		||||
 */
 | 
			
		||||
var WriteError = function(err) {
 | 
			
		||||
  if(!(this instanceof WriteError)) return new WriteError(err);
 | 
			
		||||
 | 
			
		||||
  // Define properties
 | 
			
		||||
  defineReadOnlyProperty(this, "code", err.code);
 | 
			
		||||
  defineReadOnlyProperty(this, "index", err.index);
 | 
			
		||||
  defineReadOnlyProperty(this, "errmsg", err.errmsg);
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // Define access methods
 | 
			
		||||
  this.getOperation = function() {
 | 
			
		||||
    return err.op;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.toJSON = function() {
 | 
			
		||||
    return {code: err.code, index: err.index, errmsg: err.errmsg, op: err.op};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.toString = function() {
 | 
			
		||||
    return "WriteError(" + JSON.stringify(this.toJSON()) + ")";
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Merges results into shared data structure
 | 
			
		||||
 */
 | 
			
		||||
var mergeBatchResults = function(ordered, batch, bulkResult, err, result) {
 | 
			
		||||
  // If we have an error set the result to be the err object
 | 
			
		||||
  if(err) {
 | 
			
		||||
    result = err;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Do we have a top level error stop processing and return
 | 
			
		||||
  if(result.ok == 0 && bulkResult.ok == 1) {
 | 
			
		||||
    bulkResult.ok = 0;
 | 
			
		||||
    bulkResult.error = utils.toError(result);
 | 
			
		||||
    return;
 | 
			
		||||
  } else if(result.ok == 0 && bulkResult.ok == 0) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Add lastop if available
 | 
			
		||||
  if(result.lastOp) {
 | 
			
		||||
    bulkResult.lastOp = result.lastOp;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // If we have an insert Batch type
 | 
			
		||||
  if(batch.batchType == INSERT && result.n) {
 | 
			
		||||
    bulkResult.nInserted = bulkResult.nInserted + result.n;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // If we have an insert Batch type
 | 
			
		||||
  if(batch.batchType == REMOVE && result.n) {
 | 
			
		||||
    bulkResult.nRemoved = bulkResult.nRemoved + result.n;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var nUpserted = 0;
 | 
			
		||||
 | 
			
		||||
  // We have an array of upserted values, we need to rewrite the indexes
 | 
			
		||||
  if(Array.isArray(result.upserted)) {
 | 
			
		||||
    nUpserted = result.upserted.length;
 | 
			
		||||
 | 
			
		||||
    for(var i = 0; i < result.upserted.length; i++) {
 | 
			
		||||
      bulkResult.upserted.push({
 | 
			
		||||
          index: result.upserted[i].index + batch.originalZeroIndex
 | 
			
		||||
        , _id: result.upserted[i]._id
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  } else if(result.upserted) {
 | 
			
		||||
 | 
			
		||||
    nUpserted = 1;
 | 
			
		||||
 | 
			
		||||
    bulkResult.upserted.push({
 | 
			
		||||
        index: batch.originalZeroIndex
 | 
			
		||||
      , _id: result.upserted
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // If we have an update Batch type
 | 
			
		||||
  if(batch.batchType == UPDATE && result.n) {
 | 
			
		||||
    var nModified = result.nModified;
 | 
			
		||||
    bulkResult.nUpserted = bulkResult.nUpserted + nUpserted;
 | 
			
		||||
    bulkResult.nMatched = bulkResult.nMatched + (result.n - nUpserted);
 | 
			
		||||
    
 | 
			
		||||
    if(typeof nModified == 'number') {
 | 
			
		||||
      bulkResult.nModified = bulkResult.nModified + nModified;
 | 
			
		||||
    } else {
 | 
			
		||||
      bulkResult.nModified = null;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(Array.isArray(result.writeErrors)) {
 | 
			
		||||
    for(var i = 0; i < result.writeErrors.length; i++) {
 | 
			
		||||
 | 
			
		||||
      var writeError = {
 | 
			
		||||
          index: batch.originalZeroIndex + result.writeErrors[i].index
 | 
			
		||||
        , code: result.writeErrors[i].code
 | 
			
		||||
        , errmsg: result.writeErrors[i].errmsg
 | 
			
		||||
        , op: batch.operations[result.writeErrors[i].index]
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      bulkResult.writeErrors.push(new WriteError(writeError));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(result.writeConcernError) {
 | 
			
		||||
    bulkResult.writeConcernErrors.push(new WriteConcernError(result.writeConcernError));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 
 | 
			
		||||
// Merge a legacy result into the master results
 | 
			
		||||
var mergeLegacyResults = function(_ordered, _op, _batch, _results, _result, _index) {
 | 
			
		||||
  // If we have an error already
 | 
			
		||||
  if(_results.ok == 0) return false;
 | 
			
		||||
  // Handle error
 | 
			
		||||
  if((_result.errmsg || _result.err || _result instanceof Error) && _result.wtimeout != true) {
 | 
			
		||||
    // && ((_result.wtimeout == null && _result.jnote == null && _result.wnote == null)) || _result.err == "norepl") {
 | 
			
		||||
    var code = _result.code || UNKNOWN_ERROR; // Returned error code or unknown code
 | 
			
		||||
    var errmsg = _result.errmsg || _result.err;
 | 
			
		||||
    errmsg = errmsg || _result.message;
 | 
			
		||||
 | 
			
		||||
    // Result is replication issue, rewrite error to match write command      
 | 
			
		||||
    if(_result.wnote || _result.wtimeout || _result.jnote) {
 | 
			
		||||
      // Set the code to replication error
 | 
			
		||||
      code = WRITE_CONCERN_ERROR;
 | 
			
		||||
      // Ensure we get the right error message
 | 
			
		||||
      errmsg = _result.wnote || errmsg;
 | 
			
		||||
      errmsg = _result.jnote || errmsg;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // We have an error that is a show stopper, 16544 and 13 are auth errors that should stop processing
 | 
			
		||||
    if(_result.wnote 
 | 
			
		||||
      || _result.jnote == "journaling not enabled on this server" 
 | 
			
		||||
      || _result.err == "norepl"
 | 
			
		||||
      || _result.code == 16544 
 | 
			
		||||
      || _result.code == 13) {
 | 
			
		||||
      _results.ok = 0;
 | 
			
		||||
      _results.error = utils.toError({code: code, errmsg: errmsg});
 | 
			
		||||
      return false;
 | 
			
		||||
    }    
 | 
			
		||||
 | 
			
		||||
    // Create a write error
 | 
			
		||||
    var errResult = new WriteError({
 | 
			
		||||
        index: _index
 | 
			
		||||
      , code: code
 | 
			
		||||
      , errmsg: errmsg
 | 
			
		||||
      , op: _op      
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    // Err details
 | 
			
		||||
    _results.writeErrors.push(errResult);
 | 
			
		||||
 | 
			
		||||
    // Check if we any errors
 | 
			
		||||
    if(_ordered == true 
 | 
			
		||||
      && _result.jnote == null 
 | 
			
		||||
      && _result.wnote == null 
 | 
			
		||||
      && _result.wtimeout == null) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
  } else if(_batch.batchType == INSERT) {
 | 
			
		||||
    _results.nInserted = _results.nInserted + 1;
 | 
			
		||||
  } else if(_batch.batchType == UPDATE) {
 | 
			
		||||
    // If we have an upserted value or if the user provided a custom _id value
 | 
			
		||||
    if(_result.upserted || (!_result.updatedExisting && _result.upserted == null)) {
 | 
			
		||||
      _results.nUpserted = _results.nUpserted + 1;
 | 
			
		||||
    } else {
 | 
			
		||||
      _results.nMatched = _results.nMatched + _result.n;
 | 
			
		||||
      _results.nModified = null;
 | 
			
		||||
     }
 | 
			
		||||
  } else if(_batch.batchType == REMOVE) {
 | 
			
		||||
    _results.nRemoved = _results.nRemoved + _result;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // We have a write concern error, add a write concern error to the results
 | 
			
		||||
  if(_result.wtimeout != null || _result.jnote != null || _result.wnote != null) {
 | 
			
		||||
    var error = _result.err || _result.errmsg || _result.wnote || _result.jnote || _result.wtimeout;
 | 
			
		||||
    var code = _result.code || WRITE_CONCERN_ERROR;
 | 
			
		||||
    // Push a write concern error to the list
 | 
			
		||||
    _results.writeConcernErrors.push(new WriteConcernError({errmsg: error, code: code}));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // We have an upserted field (might happen with a write concern error)
 | 
			
		||||
  if(_result.upserted) {
 | 
			
		||||
    _results.upserted.push({
 | 
			
		||||
        index: _index
 | 
			
		||||
      , _id: _result.upserted
 | 
			
		||||
    })
 | 
			
		||||
  } else if(!_result.updatedExisting && _result.upserted == null && _op.q && _op.q._id) {
 | 
			
		||||
    _results.upserted.push({
 | 
			
		||||
        index: _index
 | 
			
		||||
      , _id: _op.q._id
 | 
			
		||||
    })    
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Clone the options
 | 
			
		||||
var cloneOptions = function(options) {
 | 
			
		||||
  var clone = {};
 | 
			
		||||
  var keys = Object.keys(options);
 | 
			
		||||
  for(var i = 0; i < keys.length; i++) {
 | 
			
		||||
    clone[keys[i]] = options[keys[i]];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return clone;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Exports symbols
 | 
			
		||||
exports.BatchWriteResult = BatchWriteResult;
 | 
			
		||||
exports.WriteError = WriteError;
 | 
			
		||||
exports.Batch = Batch;
 | 
			
		||||
exports.LegacyOp = LegacyOp;
 | 
			
		||||
exports.mergeBatchResults = mergeBatchResults;
 | 
			
		||||
exports.cloneOptions = cloneOptions;
 | 
			
		||||
exports.mergeLegacyResults = mergeLegacyResults;
 | 
			
		||||
exports.INVALID_BSON_ERROR = INVALID_BSON_ERROR;
 | 
			
		||||
exports.WRITE_CONCERN_ERROR = WRITE_CONCERN_ERROR;
 | 
			
		||||
exports.MULTIPLE_ERROR = MULTIPLE_ERROR;
 | 
			
		||||
exports.UNKNOWN_ERROR = UNKNOWN_ERROR;
 | 
			
		||||
exports.INSERT = INSERT;
 | 
			
		||||
exports.UPDATE = UPDATE;
 | 
			
		||||
exports.REMOVE = REMOVE;
 | 
			
		||||
							
								
								
									
										530
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/collection/batch/ordered.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										530
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/collection/batch/ordered.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,530 @@
 | 
			
		||||
var shared = require('../shared')
 | 
			
		||||
	, common = require('./common')
 | 
			
		||||
	, utils = require('../../utils')
 | 
			
		||||
  , hasWriteCommands = utils.hasWriteCommands
 | 
			
		||||
  , WriteError = common.WriteError
 | 
			
		||||
  , BatchWriteResult = common.BatchWriteResult
 | 
			
		||||
  , LegacyOp = common.LegacyOp
 | 
			
		||||
  , ObjectID = require('bson').ObjectID
 | 
			
		||||
  , Batch = common.Batch
 | 
			
		||||
  , mergeBatchResults = common.mergeBatchResults;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create a new OrderedBulkOperation instance (INTERNAL TYPE, do not instantiate directly)
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write
 | 
			
		||||
 *  - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option)
 | 
			
		||||
 *  - **fsync**, (Boolean, default:false) write waits for fsync before returning, from MongoDB 2.6 on, fsync cannot be combined with journal
 | 
			
		||||
 *  - **j**, (Boolean, default:false) write waits for journal sync before returning
 | 
			
		||||
 *
 | 
			
		||||
 * @class Represents a OrderedBulkOperation
 | 
			
		||||
 * @param {Object} collection collection instance.
 | 
			
		||||
 * @param {Object} [options] additional options for the collection.
 | 
			
		||||
 * @return {Object} a ordered bulk operation instance.
 | 
			
		||||
 */
 | 
			
		||||
function OrderedBulkOperation (collection, options) {
 | 
			
		||||
	options = options == null ? {} : options;
 | 
			
		||||
	// TODO Bring from driver information in isMaster
 | 
			
		||||
	var self = this;
 | 
			
		||||
	var executed = false;
 | 
			
		||||
	
 | 
			
		||||
	// Current item
 | 
			
		||||
	var currentOp = null;
 | 
			
		||||
 | 
			
		||||
	// Handle to the bson serializer, used to calculate running sizes
 | 
			
		||||
  var db = collection.db;
 | 
			
		||||
	var bson = db.bson;
 | 
			
		||||
 | 
			
		||||
	// Namespace for the operation
 | 
			
		||||
  var namespace = collection.collectionName;  
 | 
			
		||||
 | 
			
		||||
  // Set max byte size
 | 
			
		||||
	var maxWriteBatchSize = db.serverConfig.checkoutWriter().maxWriteBatchSize || 1000;
 | 
			
		||||
	var maxBatchSizeBytes = db.serverConfig.checkoutWriter().maxBsonSize;
 | 
			
		||||
 | 
			
		||||
  // Get the write concern
 | 
			
		||||
  var writeConcern = shared._getWriteConcern(collection, options);
 | 
			
		||||
	
 | 
			
		||||
  // Current batch
 | 
			
		||||
  var currentBatch = null;
 | 
			
		||||
  var currentIndex = 0;
 | 
			
		||||
  var currentBatchSize = 0;
 | 
			
		||||
  var currentBatchSizeBytes = 0;
 | 
			
		||||
  var batches = [];
 | 
			
		||||
 | 
			
		||||
  // Final results
 | 
			
		||||
  var bulkResult = {
 | 
			
		||||
  	  ok: 1
 | 
			
		||||
    , writeErrors: []
 | 
			
		||||
    , writeConcernErrors: []
 | 
			
		||||
    , nInserted: 0
 | 
			
		||||
    , nUpserted: 0
 | 
			
		||||
    , nMatched: 0
 | 
			
		||||
    , nModified: 0
 | 
			
		||||
    , nRemoved: 0
 | 
			
		||||
    , upserted: []
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // Specify a full class so we can generate documentation correctly
 | 
			
		||||
	var FindOperators = function() {
 | 
			
		||||
		/**
 | 
			
		||||
		 * Add a single update document to the bulk operation
 | 
			
		||||
		 *
 | 
			
		||||
		 * @param {Object} doc update operations
 | 
			
		||||
		 * @return {OrderedBulkOperation}
 | 
			
		||||
		 * @api public
 | 
			
		||||
		 */
 | 
			
		||||
		this.update = function(updateDocument) {
 | 
			
		||||
			// Perform upsert
 | 
			
		||||
			var upsert = typeof currentOp.upsert == 'boolean' ? currentOp.upsert : false;
 | 
			
		||||
			
 | 
			
		||||
			// Establish the update command
 | 
			
		||||
			var document = {
 | 
			
		||||
					q: currentOp.selector
 | 
			
		||||
				, u: updateDocument
 | 
			
		||||
				, multi: true
 | 
			
		||||
				, upsert: upsert
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Clear out current Op
 | 
			
		||||
			currentOp = null;
 | 
			
		||||
			// Add the update document to the list
 | 
			
		||||
			return addToOperationsList(self, common.UPDATE, document);
 | 
			
		||||
		}	
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Add a single update one document to the bulk operation
 | 
			
		||||
		 *
 | 
			
		||||
		 * @param {Object} doc update operations
 | 
			
		||||
		 * @return {OrderedBulkOperation}
 | 
			
		||||
		 * @api public
 | 
			
		||||
		 */
 | 
			
		||||
		this.updateOne = function(updateDocument) {
 | 
			
		||||
			// Perform upsert
 | 
			
		||||
			var upsert = typeof currentOp.upsert == 'boolean' ? currentOp.upsert : false;
 | 
			
		||||
			
 | 
			
		||||
			// Establish the update command
 | 
			
		||||
			var document = {
 | 
			
		||||
					q: currentOp.selector
 | 
			
		||||
				, u: updateDocument
 | 
			
		||||
				, multi: false
 | 
			
		||||
				, upsert: upsert
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Clear out current Op
 | 
			
		||||
			currentOp = null;
 | 
			
		||||
			// Add the update document to the list
 | 
			
		||||
			return addToOperationsList(self, common.UPDATE, document);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Add a replace one operation to the bulk operation
 | 
			
		||||
		 *
 | 
			
		||||
		 * @param {Object} doc the new document to replace the existing one with
 | 
			
		||||
		 * @return {OrderedBulkOperation}
 | 
			
		||||
		 * @api public
 | 
			
		||||
		 */
 | 
			
		||||
		this.replaceOne = function(updateDocument) {
 | 
			
		||||
			this.updateOne(updateDocument);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Upsert modifier for update bulk operation
 | 
			
		||||
		 *
 | 
			
		||||
		 * @return {OrderedBulkOperation}
 | 
			
		||||
		 * @api public
 | 
			
		||||
		 */
 | 
			
		||||
		this.upsert = function() {
 | 
			
		||||
			currentOp.upsert = true;
 | 
			
		||||
			return this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Add a remove one operation to the bulk operation
 | 
			
		||||
		 *
 | 
			
		||||
		 * @param {Object} doc selector for the removal of documents
 | 
			
		||||
		 * @return {OrderedBulkOperation}
 | 
			
		||||
		 * @api public
 | 
			
		||||
		 */
 | 
			
		||||
		this.removeOne = function() {		
 | 
			
		||||
			// Establish the update command
 | 
			
		||||
			var document = {
 | 
			
		||||
					q: currentOp.selector
 | 
			
		||||
				, limit: 1
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Clear out current Op
 | 
			
		||||
			currentOp = null;
 | 
			
		||||
			// Add the remove document to the list
 | 
			
		||||
			return addToOperationsList(self, common.REMOVE, document);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Add a remove operation to the bulk operation
 | 
			
		||||
		 *
 | 
			
		||||
		 * @param {Object} doc selector for the single document to remove
 | 
			
		||||
		 * @return {OrderedBulkOperation}
 | 
			
		||||
		 * @api public
 | 
			
		||||
		 */
 | 
			
		||||
		this.remove = function() {
 | 
			
		||||
			// Establish the update command
 | 
			
		||||
			var document = {
 | 
			
		||||
					q: currentOp.selector
 | 
			
		||||
				, limit: 0
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Clear out current Op
 | 
			
		||||
			currentOp = null;
 | 
			
		||||
			// Add the remove document to the list
 | 
			
		||||
			return addToOperationsList(self, common.REMOVE, document);				
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Add a single insert document to the bulk operation
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param {Object} doc the document to insert
 | 
			
		||||
	 * @return {OrderedBulkOperation}
 | 
			
		||||
	 * @api public
 | 
			
		||||
	 */
 | 
			
		||||
	this.insert = function(document) {
 | 
			
		||||
		if(document._id == null) document._id = new ObjectID();
 | 
			
		||||
		return addToOperationsList(self, common.INSERT, document);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var getOrderedCommand = function(_self, _namespace, _docType, _operationDocuments) {
 | 
			
		||||
		// Set up the types of operation
 | 
			
		||||
		if(_docType == common.INSERT) {
 | 
			
		||||
			return {
 | 
			
		||||
					insert: _namespace
 | 
			
		||||
				, documents: _operationDocuments
 | 
			
		||||
				, ordered:true 
 | 
			
		||||
			}
 | 
			
		||||
		} else if(_docType == common.UPDATE) {
 | 
			
		||||
			return {
 | 
			
		||||
					update: _namespace
 | 
			
		||||
				, updates: _operationDocuments
 | 
			
		||||
				, ordered:true
 | 
			
		||||
			};
 | 
			
		||||
		} else if(_docType == common.REMOVE) {
 | 
			
		||||
			return {
 | 
			
		||||
					delete: _namespace
 | 
			
		||||
				, deletes: _operationDocuments
 | 
			
		||||
				, ordered:true
 | 
			
		||||
			};
 | 
			
		||||
		}		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Add to internal list of documents
 | 
			
		||||
	var addToOperationsList = function(_self, docType, document) {
 | 
			
		||||
    // Get the bsonSize
 | 
			
		||||
    var bsonSize = bson.calculateObjectSize(document, false);
 | 
			
		||||
    // Throw error if the doc is bigger than the max BSON size
 | 
			
		||||
    if(bsonSize >= maxBatchSizeBytes) throw utils.toError("document is larger than the maximum size " + maxBatchSizeBytes);
 | 
			
		||||
    // Create a new batch object if we don't have a current one
 | 
			
		||||
    if(currentBatch == null) currentBatch = new Batch(docType, currentIndex);
 | 
			
		||||
    
 | 
			
		||||
    // Check if we need to create a new batch
 | 
			
		||||
    if(((currentBatchSize + 1) >= maxWriteBatchSize)
 | 
			
		||||
      || ((currentBatchSizeBytes +  currentBatchSizeBytes) >= maxBatchSizeBytes)
 | 
			
		||||
      || (currentBatch.batchType != docType)) {
 | 
			
		||||
      // Save the batch to the execution stack
 | 
			
		||||
      batches.push(currentBatch);
 | 
			
		||||
      
 | 
			
		||||
      // Create a new batch
 | 
			
		||||
      currentBatch = new Batch(docType, currentIndex);
 | 
			
		||||
      
 | 
			
		||||
      // Reset the current size trackers
 | 
			
		||||
      currentBatchSize = 0;
 | 
			
		||||
      currentBatchSizeBytes = 0;
 | 
			
		||||
    } else {
 | 
			
		||||
	    // Update current batch size
 | 
			
		||||
	    currentBatchSize = currentBatchSize + 1;
 | 
			
		||||
	    currentBatchSizeBytes = currentBatchSizeBytes + bsonSize;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // We have an array of documents
 | 
			
		||||
    if(Array.isArray(document)) {
 | 
			
		||||
			throw utils.toError("operation passed in cannot be an Array");
 | 
			
		||||
    } else {
 | 
			
		||||
    	currentBatch.originalIndexes.push(currentIndex);
 | 
			
		||||
      currentBatch.operations.push(document)
 | 
			
		||||
      currentIndex = currentIndex + 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Return self
 | 
			
		||||
		return _self;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Initiate a find operation for an update/updateOne/remove/removeOne/replaceOne
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param {Object} doc
 | 
			
		||||
	 * @return {OrderedBulkOperation}
 | 
			
		||||
	 * @api public
 | 
			
		||||
	 */
 | 
			
		||||
	this.find = function(selector) {
 | 
			
		||||
		if (!selector) {
 | 
			
		||||
			throw utils.toError("Bulk find operation must specify a selector");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Save a current selector
 | 
			
		||||
		currentOp = {
 | 
			
		||||
			selector: selector
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return new FindOperators();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//
 | 
			
		||||
	// Execute next write command in a chain
 | 
			
		||||
	var executeCommands = function(callback) {
 | 
			
		||||
		if(batches.length == 0) {
 | 
			
		||||
			return callback(null, new BatchWriteResult(bulkResult));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Ordered execution of the command
 | 
			
		||||
		var batch = batches.shift();
 | 
			
		||||
		
 | 
			
		||||
		// Build the command
 | 
			
		||||
		var cmd = null;
 | 
			
		||||
 | 
			
		||||
    // Generate the right update
 | 
			
		||||
    if(batch.batchType == common.UPDATE) {
 | 
			
		||||
      cmd = { update: namespace, updates: batch.operations, ordered: true }
 | 
			
		||||
    } else if(batch.batchType == common.INSERT) {
 | 
			
		||||
      cmd = { insert: namespace, documents: batch.operations, ordered: true }
 | 
			
		||||
    } else if(batch.batchType == common.REMOVE) {
 | 
			
		||||
      cmd = { delete: namespace, deletes: batch.operations, ordered: true }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If we have a write concern
 | 
			
		||||
    if(writeConcern != null) {
 | 
			
		||||
      cmd.writeConcern = writeConcern;
 | 
			
		||||
    }    
 | 
			
		||||
 | 
			
		||||
		// Execute it
 | 
			
		||||
		db.command(cmd, function(err, result) {	
 | 
			
		||||
			// Merge the results together
 | 
			
		||||
			var mergeResult = mergeBatchResults(true, batch, bulkResult, err, result);
 | 
			
		||||
			if(mergeResult != null) {
 | 
			
		||||
				return callback(null, new BatchWriteResult(bulkResult));
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// If we had a serious error
 | 
			
		||||
			if(bulkResult.ok == 0) {
 | 
			
		||||
				return callback(bulkResult.error, null);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
      // If we are ordered and have errors and they are 
 | 
			
		||||
      // not all replication errors terminate the operation          
 | 
			
		||||
      if(bulkResult.writeErrors.length > 0) {
 | 
			
		||||
        return callback(null, new BatchWriteResult(bulkResult));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
			// Execute the next command in line
 | 
			
		||||
			executeCommands(callback);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 
 | 
			
		||||
	// Execute the inserts
 | 
			
		||||
	var executeInserts = function(_collection, _batch, _result, _callback) {
 | 
			
		||||
		if(_batch.operations.length == 0) {
 | 
			
		||||
			return _callback(null, _result);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Get the first update
 | 
			
		||||
		var document = _batch.operations.shift();
 | 
			
		||||
		var index = _batch.originalIndexes.shift();
 | 
			
		||||
		
 | 
			
		||||
		// Options for the update operation
 | 
			
		||||
		var options = writeConcern || {};
 | 
			
		||||
 | 
			
		||||
		// Execute the update
 | 
			
		||||
		_collection.insert(document, options, function(err, r) {
 | 
			
		||||
			// If we have don't have w:0 merge the result
 | 
			
		||||
			if(options.w == null || options.w != 0) {
 | 
			
		||||
				// Merge the results in 
 | 
			
		||||
				var result = common.mergeLegacyResults(true, document, _batch, bulkResult, err || r, index);
 | 
			
		||||
 | 
			
		||||
				if(result == false) {
 | 
			
		||||
					return _callback(null, new BatchWriteResult(bulkResult));
 | 
			
		||||
				}				
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Update the index
 | 
			
		||||
			_batch.currentIndex = _batch.currentIndex + 1;
 | 
			
		||||
 | 
			
		||||
			// Execute the next insert		
 | 
			
		||||
			executeInserts(_collection, _batch, _result, _callback);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//
 | 
			
		||||
	// Execute updates
 | 
			
		||||
	var executeUpdates = function(_collection, _batch, _result, _callback) {
 | 
			
		||||
		if(_batch.operations.length == 0) {
 | 
			
		||||
			return _callback(null, _result);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Get the first update
 | 
			
		||||
		var update = _batch.operations.shift();
 | 
			
		||||
		var index = _batch.originalIndexes.shift();
 | 
			
		||||
		
 | 
			
		||||
		// Options for the update operation
 | 
			
		||||
		var options = writeConcern != null ? common.cloneOptions(writeConcern) : {};
 | 
			
		||||
		
 | 
			
		||||
		// Add any additional options
 | 
			
		||||
		if(update.multi) options.multi = update.multi;
 | 
			
		||||
		if(update.upsert) options.upsert = update.upsert;
 | 
			
		||||
 | 
			
		||||
		// Execute the update
 | 
			
		||||
		_collection.update(update.q, update.u, options, function(err, r, full) {
 | 
			
		||||
			// If we have don't have w:0 merge the result
 | 
			
		||||
			if(options.w == null || options.w != 0) {
 | 
			
		||||
				// Merge the results in 
 | 
			
		||||
				var result = common.mergeLegacyResults(true, update, _batch, bulkResult, err || full, index);
 | 
			
		||||
				if(result == false) {
 | 
			
		||||
					return _callback(null, new BatchWriteResult(bulkResult));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Update the index
 | 
			
		||||
			_batch.currentIndex = _batch.currentIndex + 1;
 | 
			
		||||
 | 
			
		||||
			// Execute the next insert		
 | 
			
		||||
			executeUpdates(_collection, _batch, _result, _callback);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//
 | 
			
		||||
	// Execute updates
 | 
			
		||||
	var executeRemoves = function(_collection, _batch, _result, _callback) {
 | 
			
		||||
		if(_batch.operations.length == 0) {
 | 
			
		||||
			return _callback(null, _result);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Get the first update
 | 
			
		||||
		var remove = _batch.operations.shift();
 | 
			
		||||
		var index = _batch.originalIndexes.shift();
 | 
			
		||||
		
 | 
			
		||||
		// Options for the update operation
 | 
			
		||||
		var options = writeConcern != null ? common.cloneOptions(writeConcern) : {};
 | 
			
		||||
		
 | 
			
		||||
		// Add any additional options
 | 
			
		||||
		options.single = remove.limit == 1 ? true : false;
 | 
			
		||||
 | 
			
		||||
		// Execute the update
 | 
			
		||||
		_collection.remove(remove.q, options, function(err, r) {
 | 
			
		||||
			// If we have don't have w:0 merge the result
 | 
			
		||||
			if(options.w == null || options.w != 0) {
 | 
			
		||||
				// Merge the results in 
 | 
			
		||||
				var result = common.mergeLegacyResults(true, remove, _batch, bulkResult, err || r, index);
 | 
			
		||||
				if(result == false) {
 | 
			
		||||
					return _callback(null, new BatchWriteResult(bulkResult));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			// Update the index
 | 
			
		||||
			_batch.currentIndex = _batch.currentIndex + 1;
 | 
			
		||||
 | 
			
		||||
			// Execute the next insert		
 | 
			
		||||
			executeRemoves(_collection, _batch, _result, _callback);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//
 | 
			
		||||
	// Execute all operation in backwards compatible fashion
 | 
			
		||||
	var backwardsCompatibilityExecuteCommands = function(callback) {
 | 
			
		||||
		if(batches.length == 0) {
 | 
			
		||||
			return callback(null, new BatchWriteResult(bulkResult));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Ordered execution of the command
 | 
			
		||||
		var batch = batches.shift();
 | 
			
		||||
 | 
			
		||||
		// Process the legacy operations
 | 
			
		||||
		var processLegacyOperations = function(err, results) {
 | 
			
		||||
			// If we have any errors stop executing
 | 
			
		||||
      if(bulkResult.writeErrors.length > 0) {
 | 
			
		||||
				return callback(null, new BatchWriteResult(bulkResult));
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// If we have a top level error stop
 | 
			
		||||
			if(bulkResult.ok == 0) {
 | 
			
		||||
				return callback(bulkResult.error, null);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Execute the next step
 | 
			
		||||
			backwardsCompatibilityExecuteCommands(callback);			
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Execute an insert batch
 | 
			
		||||
		if(batch.batchType == common.INSERT) {
 | 
			
		||||
			return executeInserts(collection, batch, {n: 0}, processLegacyOperations);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Execute an update batch
 | 
			
		||||
		if(batch.batchType == common.UPDATE) {
 | 
			
		||||
			return executeUpdates(collection, batch, {n: 0}, processLegacyOperations);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Execute an update batch
 | 
			
		||||
		if(batch.batchType == common.REMOVE) {
 | 
			
		||||
			return executeRemoves(collection, batch, {n: 0}, processLegacyOperations);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute the ordered bulk operation
 | 
			
		||||
	 *
 | 
			
		||||
	 * Options
 | 
			
		||||
	 *  - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write
 | 
			
		||||
	 *  - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option)
 | 
			
		||||
	 *  - **fsync**, (Boolean, default:false) write waits for fsync before returning, from MongoDB 2.6 on, fsync cannot be combined with journal
 | 
			
		||||
	 *  - **j**, (Boolean, default:false) write waits for journal sync before returning
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param {Object} [options] additional options during update.
 | 
			
		||||
	 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from from the ordered bulk operation.
 | 
			
		||||
	 * @return {null}
 | 
			
		||||
	 * @api public
 | 
			
		||||
	 */
 | 
			
		||||
	this.execute = function(_writeConcern, callback) {
 | 
			
		||||
		if(executed) throw new utils.toError("batch cannot be re-executed");
 | 
			
		||||
		if(typeof _writeConcern == 'function') {
 | 
			
		||||
			callback = _writeConcern;
 | 
			
		||||
		} else {
 | 
			
		||||
			writeConcern = _writeConcern;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
    // If we have current batch
 | 
			
		||||
    if(currentBatch) batches.push(currentBatch);
 | 
			
		||||
 | 
			
		||||
		// If we have no operations in the bulk raise an error
 | 
			
		||||
		if(batches.length == 0) {
 | 
			
		||||
			throw utils.toError("Invalid Operation, No operations in bulk");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Check if we support bulk commands, override if needed to use legacy ops
 | 
			
		||||
		if(hasWriteCommands(db.serverConfig.checkoutWriter()))
 | 
			
		||||
			return executeCommands(callback);
 | 
			
		||||
 | 
			
		||||
		// Set nModified to null as we don't support this field
 | 
			
		||||
		bulkResult.nModified = null;
 | 
			
		||||
 | 
			
		||||
		// Run in backward compatibility mode
 | 
			
		||||
		backwardsCompatibilityExecuteCommands(callback);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns an unordered batch object
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
var initializeOrderedBulkOp = function(options) {
 | 
			
		||||
	return new OrderedBulkOperation(this, options);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.initializeOrderedBulkOp = initializeOrderedBulkOp;
 | 
			
		||||
							
								
								
									
										553
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/collection/batch/unordered.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										553
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/collection/batch/unordered.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,553 @@
 | 
			
		||||
var shared = require('../shared')
 | 
			
		||||
	, common = require('./common')
 | 
			
		||||
	, utils = require('../../utils')
 | 
			
		||||
  , hasWriteCommands = utils.hasWriteCommands
 | 
			
		||||
  , WriteError = common.WriteError
 | 
			
		||||
  , BatchWriteResult = common.BatchWriteResult
 | 
			
		||||
  , LegacyOp = common.LegacyOp
 | 
			
		||||
  , ObjectID = require('bson').ObjectID
 | 
			
		||||
  , Batch = common.Batch
 | 
			
		||||
  , mergeBatchResults = common.mergeBatchResults;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create a new UnorderedBulkOperation instance (INTERNAL TYPE, do not instantiate directly)
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write
 | 
			
		||||
 *  - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option)
 | 
			
		||||
 *  - **fsync**, (Boolean, default:false) write waits for fsync before returning, from MongoDB 2.6 on, fsync cannot be combined with journal
 | 
			
		||||
 *  - **j**, (Boolean, default:false) write waits for journal sync before returning
 | 
			
		||||
 *
 | 
			
		||||
 * @class Represents a UnorderedBulkOperation
 | 
			
		||||
 * @param {Object} collection collection instance.
 | 
			
		||||
 * @param {Object} [options] additional options for the collection.
 | 
			
		||||
 * @return {Object} a ordered bulk operation instance.
 | 
			
		||||
 */
 | 
			
		||||
var UnorderedBulkOperation = function(collection, options) {
 | 
			
		||||
	options = options == null ? {} : options;
 | 
			
		||||
 | 
			
		||||
	// Contains reference to self
 | 
			
		||||
	var self = this;
 | 
			
		||||
	// Get the namesspace for the write operations
 | 
			
		||||
  var namespace = collection.collectionName;
 | 
			
		||||
  // Used to mark operation as executed
 | 
			
		||||
  var executed = false;
 | 
			
		||||
 | 
			
		||||
	// Current item
 | 
			
		||||
	var currentOp = null;
 | 
			
		||||
	var currentIndex = 0;
 | 
			
		||||
  var batches = [];
 | 
			
		||||
 | 
			
		||||
  // The current Batches for the different operations
 | 
			
		||||
  var currentInsertBatch = null;
 | 
			
		||||
  var currentUpdateBatch = null;
 | 
			
		||||
  var currentRemoveBatch = null;
 | 
			
		||||
 | 
			
		||||
	// Handle to the bson serializer, used to calculate running sizes
 | 
			
		||||
  var db = collection.db;
 | 
			
		||||
	var bson = db.bson;
 | 
			
		||||
 | 
			
		||||
  // Set max byte size
 | 
			
		||||
	var maxBatchSizeBytes = db.serverConfig.checkoutWriter().maxBsonSize;
 | 
			
		||||
	var maxWriteBatchSize = db.serverConfig.checkoutWriter().maxWriteBatchSize || 1000;
 | 
			
		||||
 | 
			
		||||
  // Get the write concern
 | 
			
		||||
  var writeConcern = shared._getWriteConcern(collection, options);
 | 
			
		||||
 | 
			
		||||
  // Final results
 | 
			
		||||
  var bulkResult = {
 | 
			
		||||
  	  ok: 1
 | 
			
		||||
    , writeErrors: []
 | 
			
		||||
    , writeConcernErrors: []
 | 
			
		||||
    , nInserted: 0
 | 
			
		||||
    , nUpserted: 0
 | 
			
		||||
    , nMatched: 0
 | 
			
		||||
    , nModified: 0
 | 
			
		||||
    , nRemoved: 0
 | 
			
		||||
    , upserted: []
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // Specify a full class so we can generate documentation correctly
 | 
			
		||||
	var FindOperators = function() {
 | 
			
		||||
		/**
 | 
			
		||||
		 * Add a single update document to the bulk operation
 | 
			
		||||
		 *
 | 
			
		||||
		 * @param {Object} doc update operations
 | 
			
		||||
		 * @return {UnorderedBulkOperation}
 | 
			
		||||
		 * @api public
 | 
			
		||||
		 */
 | 
			
		||||
		this.update = function(updateDocument) {
 | 
			
		||||
			// Perform upsert
 | 
			
		||||
			var upsert = typeof currentOp.upsert == 'boolean' ? currentOp.upsert : false;
 | 
			
		||||
			
 | 
			
		||||
			// Establish the update command
 | 
			
		||||
			var document = {
 | 
			
		||||
					q: currentOp.selector
 | 
			
		||||
				, u: updateDocument
 | 
			
		||||
				, multi: true
 | 
			
		||||
				, upsert: upsert
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Clear out current Op
 | 
			
		||||
			currentOp = null;
 | 
			
		||||
			// Add the update document to the list
 | 
			
		||||
			return addToOperationsList(self, common.UPDATE, document);
 | 
			
		||||
		}	
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Add a single update one document to the bulk operation
 | 
			
		||||
		 *
 | 
			
		||||
		 * @param {Object} doc update operations
 | 
			
		||||
		 * @return {UnorderedBulkOperation}
 | 
			
		||||
		 * @api public
 | 
			
		||||
		 */
 | 
			
		||||
		this.updateOne = function(updateDocument) {
 | 
			
		||||
			// Perform upsert
 | 
			
		||||
			var upsert = typeof currentOp.upsert == 'boolean' ? currentOp.upsert : false;
 | 
			
		||||
			
 | 
			
		||||
			// Establish the update command
 | 
			
		||||
			var document = {
 | 
			
		||||
					q: currentOp.selector
 | 
			
		||||
				, u: updateDocument
 | 
			
		||||
				, multi: false
 | 
			
		||||
				, upsert: upsert
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Clear out current Op
 | 
			
		||||
			currentOp = null;
 | 
			
		||||
			// Add the update document to the list
 | 
			
		||||
			return addToOperationsList(self, common.UPDATE, document);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Add a replace one operation to the bulk operation
 | 
			
		||||
		 *
 | 
			
		||||
		 * @param {Object} doc the new document to replace the existing one with
 | 
			
		||||
		 * @return {UnorderedBulkOperation}
 | 
			
		||||
		 * @api public
 | 
			
		||||
		 */
 | 
			
		||||
		this.replaceOne = function(updateDocument) {
 | 
			
		||||
			this.updateOne(updateDocument);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Upsert modifier for update bulk operation
 | 
			
		||||
		 *
 | 
			
		||||
		 * @return {UnorderedBulkOperation}
 | 
			
		||||
		 * @api public
 | 
			
		||||
		 */
 | 
			
		||||
		this.upsert = function() {
 | 
			
		||||
			currentOp.upsert = true;
 | 
			
		||||
			return this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Add a remove one operation to the bulk operation
 | 
			
		||||
		 *
 | 
			
		||||
		 * @param {Object} doc selector for the removal of documents
 | 
			
		||||
		 * @return {UnorderedBulkOperation}
 | 
			
		||||
		 * @api public
 | 
			
		||||
		 */
 | 
			
		||||
		this.removeOne = function() {		
 | 
			
		||||
			// Establish the update command
 | 
			
		||||
			var document = {
 | 
			
		||||
					q: currentOp.selector
 | 
			
		||||
				, limit: 1
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Clear out current Op
 | 
			
		||||
			currentOp = null;
 | 
			
		||||
			// Add the remove document to the list
 | 
			
		||||
			return addToOperationsList(self, common.REMOVE, document);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * Add a remove operation to the bulk operation
 | 
			
		||||
		 *
 | 
			
		||||
		 * @param {Object} doc selector for the single document to remove
 | 
			
		||||
		 * @return {UnorderedBulkOperation}
 | 
			
		||||
		 * @api public
 | 
			
		||||
		 */
 | 
			
		||||
		this.remove = function() {
 | 
			
		||||
			// Establish the update command
 | 
			
		||||
			var document = {
 | 
			
		||||
					q: currentOp.selector
 | 
			
		||||
				, limit: 0
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Clear out current Op
 | 
			
		||||
			currentOp = null;
 | 
			
		||||
			// Add the remove document to the list
 | 
			
		||||
			return addToOperationsList(self, common.REMOVE, document);				
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 
 | 
			
		||||
	// Add to the operations list
 | 
			
		||||
	//
 | 
			
		||||
	var addToOperationsList = function(_self, docType, document) {
 | 
			
		||||
    // Get the bsonSize
 | 
			
		||||
    var bsonSize = bson.calculateObjectSize(document, false);
 | 
			
		||||
    // Throw error if the doc is bigger than the max BSON size
 | 
			
		||||
    if(bsonSize >= maxBatchSizeBytes) throw utils.toError("document is larger than the maximum size " + maxBatchSizeBytes);
 | 
			
		||||
    // Holds the current batch
 | 
			
		||||
    var currentBatch = null;
 | 
			
		||||
    // Get the right type of batch
 | 
			
		||||
    if(docType == common.INSERT) {
 | 
			
		||||
    	currentBatch = currentInsertBatch;
 | 
			
		||||
    } else if(docType == common.UPDATE) {
 | 
			
		||||
    	currentBatch = currentUpdateBatch;
 | 
			
		||||
    } else if(docType == common.REMOVE) {
 | 
			
		||||
    	currentBatch = currentRemoveBatch;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Create a new batch object if we don't have a current one
 | 
			
		||||
    if(currentBatch == null) currentBatch = new Batch(docType, currentIndex);
 | 
			
		||||
    
 | 
			
		||||
    // Check if we need to create a new batch
 | 
			
		||||
    if(((currentBatch.size + 1) >= maxWriteBatchSize)
 | 
			
		||||
      || ((currentBatch.sizeBytes +  bsonSize) >= maxBatchSizeBytes)
 | 
			
		||||
      || (currentBatch.batchType != docType)) {
 | 
			
		||||
      // Save the batch to the execution stack
 | 
			
		||||
      batches.push(currentBatch);
 | 
			
		||||
      
 | 
			
		||||
      // Create a new batch
 | 
			
		||||
      currentBatch = new Batch(docType, currentIndex);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // We have an array of documents
 | 
			
		||||
    if(Array.isArray(document)) {
 | 
			
		||||
    	throw utils.toError("operation passed in cannot be an Array");
 | 
			
		||||
    } else {
 | 
			
		||||
      currentBatch.operations.push(document);
 | 
			
		||||
      currentBatch.originalIndexes.push(currentIndex);
 | 
			
		||||
      currentIndex = currentIndex + 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Save back the current Batch to the right type
 | 
			
		||||
    if(docType == common.INSERT) {
 | 
			
		||||
    	currentInsertBatch = currentBatch;
 | 
			
		||||
    } else if(docType == common.UPDATE) {
 | 
			
		||||
    	currentUpdateBatch = currentBatch;
 | 
			
		||||
    } else if(docType == common.REMOVE) {
 | 
			
		||||
    	currentRemoveBatch = currentBatch;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Update current batch size
 | 
			
		||||
    currentBatch.size = currentBatch.size + 1;
 | 
			
		||||
    currentBatch.sizeBytes = currentBatch.sizeBytes + bsonSize;
 | 
			
		||||
 | 
			
		||||
    // Return self
 | 
			
		||||
		return _self;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Add a single insert document to the bulk operation
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param {Object} doc the document to insert
 | 
			
		||||
	 * @return {UnorderedBulkOperation}
 | 
			
		||||
	 * @api public
 | 
			
		||||
	 */
 | 
			
		||||
	this.insert = function(document) {
 | 
			
		||||
    if(document._id == null) document._id = new ObjectID();
 | 
			
		||||
		return addToOperationsList(self, common.INSERT, document);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Initiate a find operation for an update/updateOne/remove/removeOne/replaceOne
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param {Object} selector the selector used to locate documents for the operation
 | 
			
		||||
	 * @return {UnorderedBulkOperation}
 | 
			
		||||
	 * @api public
 | 
			
		||||
	 */
 | 
			
		||||
	this.find = function(selector) {
 | 
			
		||||
		if (!selector) {
 | 
			
		||||
			throw utils.toError("Bulk find operation must specify a selector");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Save a current selector
 | 
			
		||||
		currentOp = {
 | 
			
		||||
			selector: selector
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return new FindOperators();
 | 
			
		||||
	}	
 | 
			
		||||
 | 
			
		||||
	//
 | 
			
		||||
	// Execute the command
 | 
			
		||||
	var executeBatch = function(batch, callback) {
 | 
			
		||||
		// Contains the command we are going to execute
 | 
			
		||||
		var cmd = null;
 | 
			
		||||
 | 
			
		||||
    // Generate the right update
 | 
			
		||||
    if(batch.batchType == common.UPDATE) {
 | 
			
		||||
      cmd = { update: namespace, updates: batch.operations, ordered: false }
 | 
			
		||||
    } else if(batch.batchType == common.INSERT) {
 | 
			
		||||
      cmd = { insert: namespace, documents: batch.operations, ordered: false }
 | 
			
		||||
    } else if(batch.batchType == common.REMOVE) {
 | 
			
		||||
      cmd = { delete: namespace, deletes: batch.operations, ordered: false }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If we have a write concern
 | 
			
		||||
    if(writeConcern != null) {
 | 
			
		||||
      cmd.writeConcern = writeConcern;
 | 
			
		||||
    }    
 | 
			
		||||
 | 
			
		||||
		// Execute the write command
 | 
			
		||||
		db.command(cmd, function(err, result) {
 | 
			
		||||
			callback(null, mergeBatchResults(false, batch, bulkResult, err, result));
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//
 | 
			
		||||
	// Execute all the commands
 | 
			
		||||
	var executeBatches = function(callback) {
 | 
			
		||||
		var numberOfCommandsToExecute = batches.length;
 | 
			
		||||
		// Execute over all the batches
 | 
			
		||||
		for(var i = 0; i < batches.length; i++) {
 | 
			
		||||
			executeBatch(batches[i], function(err, result) {
 | 
			
		||||
				numberOfCommandsToExecute = numberOfCommandsToExecute - 1;
 | 
			
		||||
 | 
			
		||||
				// Execute
 | 
			
		||||
				if(numberOfCommandsToExecute == 0) {
 | 
			
		||||
					// If we have an error stop
 | 
			
		||||
					if(bulkResult.ok == 0 && callback) {
 | 
			
		||||
						return callback(bulkResult.error, null);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					callback(null, new BatchWriteResult(bulkResult));
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Execute the unordered bulk operation
 | 
			
		||||
	 *
 | 
			
		||||
	 * Options
 | 
			
		||||
	 *  - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write
 | 
			
		||||
	 *  - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option)
 | 
			
		||||
	 *  - **fsync**, (Boolean, default:false) write waits for fsync before returning, from MongoDB 2.6 on, fsync cannot be combined with journal
 | 
			
		||||
	 *  - **j**, (Boolean, default:false) write waits for journal sync before returning
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param {Object} [options] additional options during update.
 | 
			
		||||
	 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from from the unordered bulk operation.
 | 
			
		||||
	 * @return {null}
 | 
			
		||||
	 * @api public
 | 
			
		||||
	 */
 | 
			
		||||
	this.execute = function(_writeConcern, callback) {
 | 
			
		||||
		if(executed) throw utils.toError("batch cannot be re-executed");
 | 
			
		||||
		if(typeof _writeConcern == 'function') {
 | 
			
		||||
			callback = _writeConcern;
 | 
			
		||||
		} else {
 | 
			
		||||
			writeConcern = _writeConcern;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
    // If we have current batch
 | 
			
		||||
    if(currentInsertBatch) batches.push(currentInsertBatch);
 | 
			
		||||
    if(currentUpdateBatch) batches.push(currentUpdateBatch);
 | 
			
		||||
    if(currentRemoveBatch) batches.push(currentRemoveBatch);
 | 
			
		||||
 | 
			
		||||
		// If we have no operations in the bulk raise an error
 | 
			
		||||
		if(batches.length == 0) {
 | 
			
		||||
			throw utils.toError("Invalid Operation, No operations in bulk");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Check if we support bulk commands
 | 
			
		||||
		if(hasWriteCommands(db.serverConfig.checkoutWriter()))
 | 
			
		||||
			return executeBatches(function(err, result) {
 | 
			
		||||
				callback(err, result);
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
		// Set nModified to null as we don't support this field
 | 
			
		||||
		bulkResult.nModified = null;
 | 
			
		||||
 | 
			
		||||
		// Run in backward compatibility mode
 | 
			
		||||
		backwardsCompatibilityExecuteCommands(function(err, result) {
 | 
			
		||||
			callback(err, result);
 | 
			
		||||
		});
 | 
			
		||||
	}	
 | 
			
		||||
 | 
			
		||||
	// 
 | 
			
		||||
	// Execute the inserts
 | 
			
		||||
	var executeInserts = function(_collection, _batch, _result, _callback) {
 | 
			
		||||
		var totalNumberOfInserts = _batch.operations.length;
 | 
			
		||||
 | 
			
		||||
		// Options for the update operation
 | 
			
		||||
		var batchOptions = writeConcern || {};
 | 
			
		||||
 | 
			
		||||
		// Execute the op
 | 
			
		||||
		var executeLegacyInsert = function(_i, _op, _options, __callback) {
 | 
			
		||||
			// Execute the update
 | 
			
		||||
			_collection.insert(_op.operation, _options, function(err, r) {
 | 
			
		||||
				// If we have don't have w:0 merge the result
 | 
			
		||||
				if(_options.w == null || _options.w != 0) {
 | 
			
		||||
					// Merge the results in 
 | 
			
		||||
					var result = common.mergeLegacyResults(false, _op.operation, _batch, bulkResult, err || r, _op.index);
 | 
			
		||||
					if(result == false) {
 | 
			
		||||
						return _callback(null, new BatchWriteResult(bulkResult));
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				__callback(null, _result);
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Execute all the insert operations
 | 
			
		||||
		for(var i = 0; i < _batch.operations.length; i++) {
 | 
			
		||||
			var legacyOp = new LegacyOp(_batch.batchType, _batch.operations[i], _batch.originalIndexes[i]);
 | 
			
		||||
			executeLegacyInsert(i, legacyOp, batchOptions, function(err, result) {
 | 
			
		||||
				totalNumberOfInserts = totalNumberOfInserts - 1;
 | 
			
		||||
				
 | 
			
		||||
				// No more inserts
 | 
			
		||||
				if(totalNumberOfInserts == 0) {
 | 
			
		||||
					_callback(null, _result);
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//
 | 
			
		||||
	// Execute updates
 | 
			
		||||
	var executeUpdates = function(_collection, _batch, _result, _callback) {
 | 
			
		||||
		var totalNumberOfUpdates = _batch.operations.length;
 | 
			
		||||
		// Options for the update operation
 | 
			
		||||
		var batchOptions = writeConcern || {};
 | 
			
		||||
 | 
			
		||||
		// Execute the op
 | 
			
		||||
		var executeLegacyUpdate = function(_i, _op, _options, __callback) {
 | 
			
		||||
			var options = common.cloneOptions(batchOptions);
 | 
			
		||||
 | 
			
		||||
			// Add any additional options
 | 
			
		||||
			if(_op.operation.multi != null) options.multi = _op.operation.multi ? true : false;
 | 
			
		||||
			if(_op.operation.upsert != null) options.upsert = _op.operation.upsert;
 | 
			
		||||
 | 
			
		||||
			// Execute the update
 | 
			
		||||
			_collection.update(_op.operation.q, _op.operation.u, options, function(err, r, full) {
 | 
			
		||||
				// If we have don't have w:0 merge the result
 | 
			
		||||
				if(options.w == null || options.w != 0) {
 | 
			
		||||
					// Merge the results in 
 | 
			
		||||
					var result = common.mergeLegacyResults(false, _op.operation, _batch, bulkResult, err || full, _op.index);
 | 
			
		||||
					if(result == false) {
 | 
			
		||||
						return _callback(null, new BatchWriteResult(bulkResult));
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				return __callback(null, _result);
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Execute all the insert operations
 | 
			
		||||
		for(var i = 0; i < _batch.operations.length; i++) {
 | 
			
		||||
			var legacyOp = new LegacyOp(_batch.batchType, _batch.operations[i], _batch.originalIndexes[i]);
 | 
			
		||||
			executeLegacyUpdate(i, legacyOp, options, function(err, result) {
 | 
			
		||||
				totalNumberOfUpdates = totalNumberOfUpdates - 1;
 | 
			
		||||
				
 | 
			
		||||
				// No more inserts
 | 
			
		||||
				if(totalNumberOfUpdates == 0) {
 | 
			
		||||
					_callback(null, _result);
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//
 | 
			
		||||
	// Execute updates
 | 
			
		||||
	var executeRemoves = function(_collection, _batch, _result, _callback) {
 | 
			
		||||
		var totalNumberOfRemoves = _batch.operations.length;
 | 
			
		||||
		// Options for the update operation
 | 
			
		||||
		var batchOptions = writeConcern || {};
 | 
			
		||||
 | 
			
		||||
		// Execute the op
 | 
			
		||||
		var executeLegacyRemove = function(_i, _op, _options, __callback) {
 | 
			
		||||
			var options = common.cloneOptions(batchOptions);
 | 
			
		||||
 | 
			
		||||
			// Add any additional options
 | 
			
		||||
			if(_op.operation.limit != null) options.single = _op.operation.limit == 1 ? true : false;
 | 
			
		||||
 | 
			
		||||
			// Execute the update
 | 
			
		||||
			_collection.remove(_op.operation.q, options, function(err, r) {
 | 
			
		||||
				// If we have don't have w:0 merge the result
 | 
			
		||||
				if(options.w == null || options.w != 0) {
 | 
			
		||||
					// Merge the results in 
 | 
			
		||||
					var result = common.mergeLegacyResults(false, _op.operation, _batch, bulkResult, err || r, _op.index);
 | 
			
		||||
					if(result == false) {
 | 
			
		||||
						return _callback(null, new BatchWriteResult(bulkResult));
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				return __callback(null, _result);
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Execute all the insert operations
 | 
			
		||||
		for(var i = 0; i < _batch.operations.length; i++) {
 | 
			
		||||
			var legacyOp = new LegacyOp(_batch.batchType, _batch.operations[i], _batch.originalIndexes[i]);
 | 
			
		||||
			executeLegacyRemove(i, legacyOp, options, function(err, result) {
 | 
			
		||||
				totalNumberOfRemoves = totalNumberOfRemoves - 1;
 | 
			
		||||
				
 | 
			
		||||
				// No more inserts
 | 
			
		||||
				if(totalNumberOfRemoves == 0) {
 | 
			
		||||
					_callback(null, _result);
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//
 | 
			
		||||
	// Execute all operation in backwards compatible fashion
 | 
			
		||||
	var backwardsCompatibilityExecuteCommands = function(callback) {
 | 
			
		||||
		if(batches.length == 0) {
 | 
			
		||||
			return callback(null, new BatchWriteResult(bulkResult));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Ordered execution of the command
 | 
			
		||||
		var batch = batches.shift();
 | 
			
		||||
 | 
			
		||||
		// Process the legacy operations
 | 
			
		||||
		var processLegacyOperations = function(err, results) {
 | 
			
		||||
			// Merge the results together
 | 
			
		||||
			var mergeResult = mergeBatchResults(false, batch, bulkResult, err, results);
 | 
			
		||||
			if(mergeResult != null) {
 | 
			
		||||
				return callback(null, mergeResult)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// If we have an error stop
 | 
			
		||||
			if(bulkResult.ok == 0 && callback) {
 | 
			
		||||
				var internalCallback = callback;
 | 
			
		||||
				callback = null;
 | 
			
		||||
				return internalCallback(bulkResult.error, null);
 | 
			
		||||
			} else if(bulkResult.ok == 0 && callback == null) {
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Execute the next step
 | 
			
		||||
			backwardsCompatibilityExecuteCommands(callback);			
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Execute an insert batch
 | 
			
		||||
		if(batch.batchType == common.INSERT) {
 | 
			
		||||
			return executeInserts(collection, batch, {n: 0}, processLegacyOperations);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Execute an update batch
 | 
			
		||||
		if(batch.batchType == common.UPDATE) {
 | 
			
		||||
			return executeUpdates(collection, batch, {n: 0}, processLegacyOperations);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Execute an update batch
 | 
			
		||||
		if(batch.batchType == common.REMOVE) {
 | 
			
		||||
			return executeRemoves(collection, batch, {n: 0}, processLegacyOperations);
 | 
			
		||||
		}
 | 
			
		||||
	}	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns an unordered batch object
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
var initializeUnorderedBulkOp = function(options) {
 | 
			
		||||
	return new UnorderedBulkOperation(this, options);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.initializeUnorderedBulkOp = initializeUnorderedBulkOp;
 | 
			
		||||
							
								
								
									
										139
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/collection/commands.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										139
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/collection/commands.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,139 @@
 | 
			
		||||
var shared = require('./shared')
 | 
			
		||||
  , utils = require('../utils')
 | 
			
		||||
  , f = require('util').format
 | 
			
		||||
  , DbCommand = require('../commands/db_command').DbCommand;
 | 
			
		||||
 | 
			
		||||
var stats = function stats(options, callback) {
 | 
			
		||||
  var args = Array.prototype.slice.call(arguments, 0);
 | 
			
		||||
  callback = args.pop();
 | 
			
		||||
  // Fetch all commands
 | 
			
		||||
  options = args.length ? args.shift() || {} : {};
 | 
			
		||||
 | 
			
		||||
  // Build command object
 | 
			
		||||
  var commandObject = {
 | 
			
		||||
    collStats:this.collectionName,
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Check if we have the scale value
 | 
			
		||||
  if(options['scale'] != null) commandObject['scale'] = options['scale'];
 | 
			
		||||
 | 
			
		||||
  // Ensure we have the right read preference inheritance
 | 
			
		||||
  options.readPreference = shared._getReadConcern(this, options);
 | 
			
		||||
 | 
			
		||||
  // Execute the command
 | 
			
		||||
  this.db.command(commandObject, options, callback);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var count = function count(query, options, callback) {
 | 
			
		||||
  var args = Array.prototype.slice.call(arguments, 0);
 | 
			
		||||
  callback = args.pop();
 | 
			
		||||
  query = args.length ? args.shift() || {} : {};
 | 
			
		||||
  options = args.length ? args.shift() || {} : {};
 | 
			
		||||
  var skip = options.skip;
 | 
			
		||||
  var limit = options.limit;
 | 
			
		||||
  var hint = options.hint;
 | 
			
		||||
  var maxTimeMS = options.maxTimeMS;
 | 
			
		||||
 | 
			
		||||
  // Final query
 | 
			
		||||
  var cmd = {
 | 
			
		||||
      'count': this.collectionName
 | 
			
		||||
    , 'query': query
 | 
			
		||||
    , 'fields': null
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // Add limit and skip if defined
 | 
			
		||||
  if(typeof skip == 'number') cmd.skip = skip;
 | 
			
		||||
  if(typeof limit == 'number') cmd.limit = limit;
 | 
			
		||||
  if(hint) cmd.hint = hint;
 | 
			
		||||
 | 
			
		||||
  // Ensure we have the right read preference inheritance
 | 
			
		||||
  options.readPreference = shared._getReadConcern(this, options);
 | 
			
		||||
 | 
			
		||||
  // Execute the command
 | 
			
		||||
  this.db.command(cmd, options, function(err, result) {
 | 
			
		||||
    if(err) return callback(err);
 | 
			
		||||
    callback(null, result.n);
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var distinct = function distinct(key, query, options, callback) {
 | 
			
		||||
  var args = Array.prototype.slice.call(arguments, 1);
 | 
			
		||||
  callback = args.pop();
 | 
			
		||||
  query = args.length ? args.shift() || {} : {};
 | 
			
		||||
  options = args.length ? args.shift() || {} : {};
 | 
			
		||||
  var maxTimeMS = options.maxTimeMS;
 | 
			
		||||
 | 
			
		||||
  var cmd = {
 | 
			
		||||
      'distinct': this.collectionName
 | 
			
		||||
    , 'key': key
 | 
			
		||||
    , 'query': query
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // Ensure we have the right read preference inheritance
 | 
			
		||||
  options.readPreference = shared._getReadConcern(this, options);
 | 
			
		||||
 | 
			
		||||
  // Execute the command
 | 
			
		||||
  this.db.command(cmd, options, function(err, result) {
 | 
			
		||||
    if(err) return callback(err);
 | 
			
		||||
    callback(null, result.values);
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var rename = function rename (newName, options, callback) {
 | 
			
		||||
  var self = this;
 | 
			
		||||
  if(typeof options == 'function') {
 | 
			
		||||
    callback = options;
 | 
			
		||||
    options = {}
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Get collection class
 | 
			
		||||
  var Collection = require('../collection').Collection;
 | 
			
		||||
  // Ensure the new name is valid
 | 
			
		||||
  shared.checkCollectionName(newName);
 | 
			
		||||
  
 | 
			
		||||
  // Build the command
 | 
			
		||||
  var renameCollection = self.db.databaseName + "." + self.collectionName;
 | 
			
		||||
  var toCollection = self.db.databaseName + "." + newName;
 | 
			
		||||
  var dropTarget = typeof options.dropTarget == 'boolean' ? options.dropTarget : false;
 | 
			
		||||
  var cmd = {'renameCollection':renameCollection, 'to':toCollection, 'dropTarget':dropTarget};
 | 
			
		||||
 | 
			
		||||
  // Execute against admin
 | 
			
		||||
  self.db.admin().command(cmd, options, function(err, result) {
 | 
			
		||||
    if(err) return callback(err, null);
 | 
			
		||||
    var doc = result.documents[0];
 | 
			
		||||
    // We have an error
 | 
			
		||||
    if(doc.errmsg) return callback(utils.toError(doc), null);
 | 
			
		||||
    try {
 | 
			
		||||
      return callback(null, new Collection(self.db, newName, self.db.pkFactory));
 | 
			
		||||
    } catch(err) {
 | 
			
		||||
      return callback(utils.toError(err), null);
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var options = function options(callback) {
 | 
			
		||||
  var self = this;
 | 
			
		||||
 | 
			
		||||
  self.db.listCollections({name: self.collectionName}).toArray(function(err, collections) {
 | 
			
		||||
    if(err) return callback(err);
 | 
			
		||||
    if(collections.length == 0) return callback(utils.toError(f("collection %s.%s not found", self.db.databaseName, self.collectionName)));
 | 
			
		||||
    callback(err, collections[0].options || null);      
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var isCapped = function isCapped(callback) {
 | 
			
		||||
  this.options(function(err, document) {
 | 
			
		||||
    if(err != null) {
 | 
			
		||||
      callback(err);
 | 
			
		||||
    } else {
 | 
			
		||||
      callback(null, document && document.capped);
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
exports.stats = stats;
 | 
			
		||||
exports.count = count;
 | 
			
		||||
exports.distinct = distinct;
 | 
			
		||||
exports.rename = rename;
 | 
			
		||||
exports.options = options;
 | 
			
		||||
exports.isCapped = isCapped;
 | 
			
		||||
							
								
								
									
										811
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/collection/core.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										811
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/collection/core.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,811 @@
 | 
			
		||||
var InsertCommand = require('../commands/insert_command').InsertCommand
 | 
			
		||||
  , DeleteCommand = require('../commands/delete_command').DeleteCommand
 | 
			
		||||
  , UpdateCommand = require('../commands/update_command').UpdateCommand
 | 
			
		||||
  , DbCommand = require('../commands/db_command').DbCommand
 | 
			
		||||
  , utils = require('../utils')
 | 
			
		||||
  , hasWriteCommands = require('../utils').hasWriteCommands
 | 
			
		||||
  , shared = require('./shared');
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Precompiled regexes
 | 
			
		||||
 * @ignore
 | 
			
		||||
 **/
 | 
			
		||||
var eErrorMessages = /No matching object found/;
 | 
			
		||||
 | 
			
		||||
// ***************************************************
 | 
			
		||||
// Insert function
 | 
			
		||||
// ***************************************************
 | 
			
		||||
var insert = function insert (docs, options, callback) {
 | 
			
		||||
  if ('function' === typeof options) callback = options, options = {};
 | 
			
		||||
  if(options == null) options = {};
 | 
			
		||||
  if(!('function' === typeof callback)) callback = null;
 | 
			
		||||
 | 
			
		||||
  // Get a connection
 | 
			
		||||
  var connection = this.db.serverConfig.checkoutWriter();
 | 
			
		||||
  if(connection instanceof Error && connection.code == -5000) return callback(connection);
 | 
			
		||||
  var useLegacyOps = options.useLegacyOps == null || options.useLegacyOps == false ? false : true;
 | 
			
		||||
  // If we support write commands let's perform the insert using it  
 | 
			
		||||
  if(!useLegacyOps && hasWriteCommands(connection) 
 | 
			
		||||
    && !Buffer.isBuffer(docs) 
 | 
			
		||||
    && !(Array.isArray(docs) && docs.length > 0 && Buffer.isBuffer(docs[0]))) {
 | 
			
		||||
      insertWithWriteCommands(this, Array.isArray(docs) ? docs : [docs], options, callback);
 | 
			
		||||
      return this
 | 
			
		||||
  } 
 | 
			
		||||
 | 
			
		||||
  // Backwards compatibility
 | 
			
		||||
  insertAll(this, Array.isArray(docs) ? docs : [docs], options, callback);
 | 
			
		||||
  return this;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Uses the new write commands available from 2.6 >
 | 
			
		||||
//
 | 
			
		||||
var insertWithWriteCommands = function(self, docs, options, callback) {
 | 
			
		||||
  // Get the intended namespace for the operation
 | 
			
		||||
  var namespace = self.collectionName;
 | 
			
		||||
 | 
			
		||||
  // Ensure we have no \x00 bytes in the name causing wrong parsing
 | 
			
		||||
  if(!!~namespace.indexOf("\x00")) {
 | 
			
		||||
    return callback(new Error("namespace cannot contain a null character"), null);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Check if we have passed in continue on error
 | 
			
		||||
  var continueOnError = typeof options['keepGoing'] == 'boolean' 
 | 
			
		||||
    ? options['keepGoing'] : false;
 | 
			
		||||
  continueOnError = typeof options['continueOnError'] == 'boolean' 
 | 
			
		||||
    ? options['continueOnError'] : continueOnError;
 | 
			
		||||
 | 
			
		||||
  // Do we serialzie functions
 | 
			
		||||
  var serializeFunctions = typeof options.serializeFunctions != 'boolean' 
 | 
			
		||||
    ? self.serializeFunctions : options.serializeFunctions;
 | 
			
		||||
 | 
			
		||||
  // Checkout a write connection
 | 
			
		||||
  var connection = self.db.serverConfig.checkoutWriter();  
 | 
			
		||||
  if(connection instanceof Error && connection.code == -5000) return callback(connection);
 | 
			
		||||
 | 
			
		||||
  // Do we return the actual result document
 | 
			
		||||
  var fullResult = typeof options.fullResult == 'boolean' ? options.fullResult : false;
 | 
			
		||||
 | 
			
		||||
  // Collect errorOptions
 | 
			
		||||
  var errorOptions = shared._getWriteConcern(self, options);
 | 
			
		||||
 | 
			
		||||
  // If we have a write command with no callback and w:0 fail
 | 
			
		||||
  if(errorOptions.w && errorOptions.w != 0 && callback == null) {
 | 
			
		||||
    throw new Error("writeConcern requires callback")
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Add the documents and decorate them with id's if they have none
 | 
			
		||||
  for(var index = 0, len = docs.length; index < len; ++index) {
 | 
			
		||||
    var doc = docs[index];
 | 
			
		||||
 | 
			
		||||
    // Add id to each document if it's not already defined
 | 
			
		||||
    if (!(Buffer.isBuffer(doc))
 | 
			
		||||
      && doc['_id'] == null
 | 
			
		||||
      && self.db.forceServerObjectId != true
 | 
			
		||||
      && options.forceServerObjectId != true) {
 | 
			
		||||
        doc['_id'] = self.pkFactory.createPk();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Single document write
 | 
			
		||||
  if(docs.length == 1) {
 | 
			
		||||
    // Create the write command
 | 
			
		||||
    var write_command = {
 | 
			
		||||
        insert: namespace
 | 
			
		||||
      , writeConcern: errorOptions
 | 
			
		||||
      , ordered: !continueOnError
 | 
			
		||||
      , documents: docs
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Execute the write command
 | 
			
		||||
    return self.db.command(write_command
 | 
			
		||||
      , { connection:connection
 | 
			
		||||
        , checkKeys: typeof options.checkKeys == 'boolean' ? options.checkKeys : true
 | 
			
		||||
        , serializeFunctions: serializeFunctions
 | 
			
		||||
        , writeCommand: true }
 | 
			
		||||
      , function(err, result) {  
 | 
			
		||||
        if(errorOptions.w == 0 && typeof callback == 'function') return callback(null, null);
 | 
			
		||||
        if(errorOptions.w == 0) return;
 | 
			
		||||
        if(callback == null) return;
 | 
			
		||||
        if(err != null) {
 | 
			
		||||
          return callback(err, null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Result has an error
 | 
			
		||||
        if(!result.ok || Array.isArray(result.writeErrors) && result.writeErrors.length > 0) {
 | 
			
		||||
          var error = utils.toError(result.writeErrors[0].errmsg);
 | 
			
		||||
          error.code = result.writeErrors[0].code;
 | 
			
		||||
          error.err = result.writeErrors[0].errmsg;
 | 
			
		||||
          error.message = result.writeErrors[0].errmsg;
 | 
			
		||||
 | 
			
		||||
          if (fullResult) return callback(error, result != null ? result : null);
 | 
			
		||||
          // Return the error
 | 
			
		||||
          return callback(error, null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(fullResult) return callback(null, result);
 | 
			
		||||
        // Return the results for a whole batch
 | 
			
		||||
        callback(null, docs)
 | 
			
		||||
    });    
 | 
			
		||||
  } else {
 | 
			
		||||
    try {
 | 
			
		||||
      // Multiple document write (use bulk)
 | 
			
		||||
      var bulk = !continueOnError ? self.initializeOrderedBulkOp() : self.initializeUnorderedBulkOp();
 | 
			
		||||
      // Add all the documents
 | 
			
		||||
      for(var i = 0; i < docs.length;i++) {
 | 
			
		||||
        bulk.insert(docs[i]);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Execute the command
 | 
			
		||||
      bulk.execute(errorOptions, function(err, result) {
 | 
			
		||||
        if(errorOptions.w == 0 && typeof callback == 'function') return callback(null, null);
 | 
			
		||||
        if(errorOptions.w == 0) return;
 | 
			
		||||
        if(callback == null) return;
 | 
			
		||||
        if(err) return callback(err, null);
 | 
			
		||||
        if(result.hasWriteErrors()) {
 | 
			
		||||
          var error = result.getWriteErrors()[0];
 | 
			
		||||
          error.code = result.getWriteErrors()[0].code;
 | 
			
		||||
          error.err = result.getWriteErrors()[0].errmsg;
 | 
			
		||||
          error.message = result.getWriteErrors()[0].errmsg;
 | 
			
		||||
          
 | 
			
		||||
          if (fullResult) return callback(error, result != null ? result : null);
 | 
			
		||||
          // Return the error
 | 
			
		||||
          return callback(error, null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(fullResult) return callback(null, result != null ? result : null);
 | 
			
		||||
        // Return the results for a whole batch
 | 
			
		||||
        callback(null, docs)
 | 
			
		||||
      });
 | 
			
		||||
    } catch(err) {
 | 
			
		||||
      callback(utils.toError(err), null);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Uses pre 2.6 OP_INSERT wire protocol
 | 
			
		||||
//
 | 
			
		||||
var insertAll = function insertAll (self, docs, options, callback) {
 | 
			
		||||
  if('function' === typeof options) callback = options, options = {};
 | 
			
		||||
  if(options == null) options = {};
 | 
			
		||||
  if(!('function' === typeof callback)) callback = null;
 | 
			
		||||
 | 
			
		||||
  // Insert options (flags for insert)
 | 
			
		||||
  var insertFlags = {};
 | 
			
		||||
  // If we have a mongodb version >= 1.9.1 support keepGoing attribute
 | 
			
		||||
  if(options['keepGoing'] != null) {
 | 
			
		||||
    insertFlags['keepGoing'] = options['keepGoing'];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // If we have a mongodb version >= 1.9.1 support keepGoing attribute
 | 
			
		||||
  if(options['continueOnError'] != null) {
 | 
			
		||||
    insertFlags['continueOnError'] = options['continueOnError'];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // DbName
 | 
			
		||||
  var dbName = options['dbName'];
 | 
			
		||||
  // If no dbname defined use the db one
 | 
			
		||||
  if(dbName == null) {
 | 
			
		||||
    dbName = self.db.databaseName;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Either use override on the function, or go back to default on either the collection
 | 
			
		||||
  // level or db
 | 
			
		||||
  if(options['serializeFunctions'] != null) {
 | 
			
		||||
    insertFlags['serializeFunctions'] = options['serializeFunctions'];
 | 
			
		||||
  } else {
 | 
			
		||||
    insertFlags['serializeFunctions'] = self.serializeFunctions;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Get checkKeys value
 | 
			
		||||
  var checkKeys = typeof options.checkKeys != 'boolean' ? true : options.checkKeys;
 | 
			
		||||
 | 
			
		||||
  // Do we return the actual result document
 | 
			
		||||
  var fullResult = typeof options.fullResult == 'boolean' ? options.fullResult : false;
 | 
			
		||||
 | 
			
		||||
  // Pass in options
 | 
			
		||||
  var insertCommand = new InsertCommand(
 | 
			
		||||
      self.db
 | 
			
		||||
    , dbName + "." + self.collectionName, checkKeys, insertFlags);
 | 
			
		||||
 | 
			
		||||
  // Add the documents and decorate them with id's if they have none
 | 
			
		||||
  for(var index = 0, len = docs.length; index < len; ++index) {
 | 
			
		||||
    var doc = docs[index];
 | 
			
		||||
 | 
			
		||||
    // Add id to each document if it's not already defined
 | 
			
		||||
    if (!(Buffer.isBuffer(doc))
 | 
			
		||||
      && doc['_id'] == null
 | 
			
		||||
      && self.db.forceServerObjectId != true
 | 
			
		||||
      && options.forceServerObjectId != true) {
 | 
			
		||||
        doc['_id'] = self.pkFactory.createPk();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    insertCommand.add(doc);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Collect errorOptions
 | 
			
		||||
  var errorOptions = shared._getWriteConcern(self, options);
 | 
			
		||||
  // Default command options
 | 
			
		||||
  var commandOptions = {};
 | 
			
		||||
  // If safe is defined check for error message
 | 
			
		||||
  if(shared._hasWriteConcern(errorOptions) && typeof callback == 'function') {
 | 
			
		||||
    // Set safe option
 | 
			
		||||
    commandOptions['safe'] = errorOptions;
 | 
			
		||||
    // If we have an error option
 | 
			
		||||
    if(typeof errorOptions == 'object') {
 | 
			
		||||
      var keys = Object.keys(errorOptions);
 | 
			
		||||
      for(var i = 0; i < keys.length; i++) {
 | 
			
		||||
        commandOptions[keys[i]] = errorOptions[keys[i]];
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If we have a passed in connection use it
 | 
			
		||||
    if(options.connection) {
 | 
			
		||||
      commandOptions.connection = options.connection;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Execute command with safe options (rolls up both command and safe command into one and executes them on the same connection)
 | 
			
		||||
    self.db._executeInsertCommand(insertCommand, commandOptions, handleWriteResults(function (err, results) {
 | 
			
		||||
      if(err) return callback(err, null);
 | 
			
		||||
      if(results == null) return callback(new Error("command failed to return result"));
 | 
			
		||||
      if(fullResult) return callback(null, results);
 | 
			
		||||
      callback(null, docs);
 | 
			
		||||
    }));
 | 
			
		||||
  } else if(shared._hasWriteConcern(errorOptions) && callback == null) {
 | 
			
		||||
    throw new Error("Cannot use a writeConcern without a provided callback");
 | 
			
		||||
  } else {
 | 
			
		||||
    // Execute the call without a write concern
 | 
			
		||||
    var result = self.db._executeInsertCommand(insertCommand, commandOptions);
 | 
			
		||||
    // If no callback just return
 | 
			
		||||
    if(!callback) return;
 | 
			
		||||
    // If error return error
 | 
			
		||||
    if(result instanceof Error) {
 | 
			
		||||
      return callback(result);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Otherwise just return
 | 
			
		||||
    return callback(null, docs);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// ***************************************************
 | 
			
		||||
// Remove function
 | 
			
		||||
// ***************************************************
 | 
			
		||||
var removeWithWriteCommands = function(self, selector, options, callback) {
 | 
			
		||||
  if('function' === typeof selector) {
 | 
			
		||||
    callback = selector;
 | 
			
		||||
    selector = options = {};
 | 
			
		||||
  } else if ('function' === typeof options) {
 | 
			
		||||
    callback = options;
 | 
			
		||||
    options = {};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Get the intended namespace for the operation
 | 
			
		||||
  var namespace = self.collectionName;
 | 
			
		||||
 | 
			
		||||
  // Ensure we have no \x00 bytes in the name causing wrong parsing
 | 
			
		||||
  if(!!~namespace.indexOf("\x00")) {
 | 
			
		||||
    return callback(new Error("namespace cannot contain a null character"), null);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Set default empty selector if none
 | 
			
		||||
  selector = selector == null ? {} : selector;
 | 
			
		||||
 | 
			
		||||
  // Check if we have passed in continue on error
 | 
			
		||||
  var continueOnError = typeof options['keepGoing'] == 'boolean' 
 | 
			
		||||
    ? options['keepGoing'] : false;
 | 
			
		||||
  continueOnError = typeof options['continueOnError'] == 'boolean' 
 | 
			
		||||
    ? options['continueOnError'] : continueOnError;
 | 
			
		||||
 | 
			
		||||
  // Do we serialzie functions
 | 
			
		||||
  var serializeFunctions = typeof options.serializeFunctions != 'boolean' 
 | 
			
		||||
    ? self.serializeFunctions : options.serializeFunctions;
 | 
			
		||||
 | 
			
		||||
  // Checkout a write connection
 | 
			
		||||
  var connection = self.db.serverConfig.checkoutWriter();  
 | 
			
		||||
  if(connection instanceof Error && connection.code == -5000) return callback(connection);
 | 
			
		||||
 | 
			
		||||
  // Figure out the value of top
 | 
			
		||||
  var limit = options.single == true ? 1 : 0;
 | 
			
		||||
  var upsert = typeof options.upsert == 'boolean' ? options.upsert : false;
 | 
			
		||||
 | 
			
		||||
  // Do we return the actual result document
 | 
			
		||||
  var fullResult = typeof options.fullResult == 'boolean' ? options.fullResult : false;
 | 
			
		||||
 | 
			
		||||
  // Collect errorOptions
 | 
			
		||||
  var errorOptions = shared._getWriteConcern(self, options);
 | 
			
		||||
 | 
			
		||||
  // If we have a write command with no callback and w:0 fail
 | 
			
		||||
  if(errorOptions.w && errorOptions.w != 0 && callback == null) {
 | 
			
		||||
    throw new Error("writeConcern requires callback")
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Create the write command
 | 
			
		||||
  var write_command = {
 | 
			
		||||
    delete: namespace,
 | 
			
		||||
    writeConcern: errorOptions,
 | 
			
		||||
    ordered: !continueOnError,
 | 
			
		||||
    deletes: [{
 | 
			
		||||
      q : selector,
 | 
			
		||||
      limit: limit
 | 
			
		||||
    }]
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Execute the write command
 | 
			
		||||
  self.db.command(write_command
 | 
			
		||||
    , { connection:connection
 | 
			
		||||
      , checkKeys: false
 | 
			
		||||
      , serializeFunctions: serializeFunctions
 | 
			
		||||
      , writeCommand: true }
 | 
			
		||||
    , function(err, result) {  
 | 
			
		||||
      if(errorOptions.w == 0 && typeof callback == 'function') return callback(null, null);
 | 
			
		||||
      if(errorOptions.w == 0) return;
 | 
			
		||||
      if(callback == null) return;
 | 
			
		||||
      if(err != null) {
 | 
			
		||||
        return callback(err, null);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Result has an error
 | 
			
		||||
      if(!result.ok || Array.isArray(result.writeErrors) && result.writeErrors.length > 0) {
 | 
			
		||||
        var error = utils.toError(result.writeErrors[0].errmsg);
 | 
			
		||||
        error.code = result.writeErrors[0].code;
 | 
			
		||||
        error.err = result.writeErrors[0].errmsg;
 | 
			
		||||
        error.message = result.writeErrors[0].errmsg;
 | 
			
		||||
        // Return the error
 | 
			
		||||
        return callback(error, null);
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      if(fullResult) return callback(null, result);
 | 
			
		||||
      // Backward compatibility format
 | 
			
		||||
      var r = backWardsCompatibiltyResults(result, 'remove');      
 | 
			
		||||
      // Return the results for a whole batch
 | 
			
		||||
      callback(null, r.n, r)
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var remove = function remove(selector, options, callback) {
 | 
			
		||||
  if('function' === typeof options) callback = options, options = null;
 | 
			
		||||
  if(options == null) options = {};
 | 
			
		||||
  if(!('function' === typeof callback)) callback = null;
 | 
			
		||||
 | 
			
		||||
  // Get a connection
 | 
			
		||||
  var connection = this.db.serverConfig.checkoutWriter();
 | 
			
		||||
  if(connection instanceof Error && connection.code == -5000) return callback(connection);
 | 
			
		||||
  var useLegacyOps = options.useLegacyOps == null || options.useLegacyOps == false ? false : true;
 | 
			
		||||
 | 
			
		||||
  // If we support write commands let's perform the insert using it  
 | 
			
		||||
  if(!useLegacyOps && hasWriteCommands(connection) && !Buffer.isBuffer(selector)) {
 | 
			
		||||
    return removeWithWriteCommands(this, selector, options, callback);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if ('function' === typeof selector) {
 | 
			
		||||
    callback = selector;
 | 
			
		||||
    selector = options = {};
 | 
			
		||||
  } else if ('function' === typeof options) {
 | 
			
		||||
    callback = options;
 | 
			
		||||
    options = {};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Ensure options
 | 
			
		||||
  if(options == null) options = {};
 | 
			
		||||
  if(!('function' === typeof callback)) callback = null;
 | 
			
		||||
  // Ensure we have at least an empty selector
 | 
			
		||||
  selector = selector == null ? {} : selector;
 | 
			
		||||
  // Set up flags for the command, if we have a single document remove
 | 
			
		||||
  var flags = 0 | (options.single ? 1 : 0);
 | 
			
		||||
 | 
			
		||||
  // Do we return the actual result document
 | 
			
		||||
  var fullResult = typeof options.fullResult == 'boolean' ? options.fullResult : false;
 | 
			
		||||
 | 
			
		||||
  // DbName
 | 
			
		||||
  var dbName = options['dbName'];
 | 
			
		||||
  // If no dbname defined use the db one
 | 
			
		||||
  if(dbName == null) {
 | 
			
		||||
    dbName = this.db.databaseName;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Create a delete command
 | 
			
		||||
  var deleteCommand = new DeleteCommand(
 | 
			
		||||
      this.db
 | 
			
		||||
    , dbName + "." + this.collectionName
 | 
			
		||||
    , selector
 | 
			
		||||
    , flags);
 | 
			
		||||
 | 
			
		||||
  var self = this;
 | 
			
		||||
  var errorOptions = shared._getWriteConcern(self, options);
 | 
			
		||||
 | 
			
		||||
  // Execute the command, do not add a callback as it's async
 | 
			
		||||
  if(shared._hasWriteConcern(errorOptions) && typeof callback == 'function') {
 | 
			
		||||
    // Insert options
 | 
			
		||||
    var commandOptions = {};
 | 
			
		||||
    // Set safe option
 | 
			
		||||
    commandOptions['safe'] = true;
 | 
			
		||||
    // If we have an error option
 | 
			
		||||
    if(typeof errorOptions == 'object') {
 | 
			
		||||
      var keys = Object.keys(errorOptions);
 | 
			
		||||
      for(var i = 0; i < keys.length; i++) {
 | 
			
		||||
        commandOptions[keys[i]] = errorOptions[keys[i]];
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If we have a passed in connection use it
 | 
			
		||||
    if(options.connection) {
 | 
			
		||||
      commandOptions.connection = options.connection;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Execute command with safe options (rolls up both command and safe command into one and executes them on the same connection)
 | 
			
		||||
    this.db._executeRemoveCommand(deleteCommand, commandOptions, handleWriteResults(function (err, results) {
 | 
			
		||||
      if(err) return callback(err, null);
 | 
			
		||||
      if(results == null) return callback(new Error("command failed to return result"));
 | 
			
		||||
      if(fullResult) return callback(null, results);
 | 
			
		||||
      callback(null, results[0].n);
 | 
			
		||||
    }));
 | 
			
		||||
  } else if(shared._hasWriteConcern(errorOptions) && callback == null) {
 | 
			
		||||
    throw new Error("Cannot use a writeConcern without a provided callback");
 | 
			
		||||
  } else {
 | 
			
		||||
    var result = this.db._executeRemoveCommand(deleteCommand);
 | 
			
		||||
    // If no callback just return
 | 
			
		||||
    if (!callback) return;
 | 
			
		||||
    // If error return error
 | 
			
		||||
    if (result instanceof Error) {
 | 
			
		||||
      return callback(result);
 | 
			
		||||
    }
 | 
			
		||||
    // Otherwise just return
 | 
			
		||||
    return callback();
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// ***************************************************
 | 
			
		||||
// Save function
 | 
			
		||||
// ***************************************************
 | 
			
		||||
var save = function save(doc, options, callback) {
 | 
			
		||||
  if('function' === typeof options) callback = options, options = null;
 | 
			
		||||
  if(options == null) options = {};
 | 
			
		||||
  if(!('function' === typeof callback)) callback = null;
 | 
			
		||||
  // Throw an error if attempting to perform a bulk operation
 | 
			
		||||
  if(Array.isArray(doc)) throw new Error("doc parameter must be a single document");
 | 
			
		||||
  // Extract the id, if we have one we need to do a update command
 | 
			
		||||
  var id = doc['_id'];
 | 
			
		||||
  var commandOptions = shared._getWriteConcern(this, options);
 | 
			
		||||
  if(options.connection) commandOptions.connection = options.connection;
 | 
			
		||||
  if(typeof options.fullResult == 'boolean') commandOptions.fullResult = options.fullResult;
 | 
			
		||||
 | 
			
		||||
  if(id != null) {
 | 
			
		||||
    commandOptions.upsert = true;
 | 
			
		||||
    this.update({ _id: id }, doc, commandOptions, callback);
 | 
			
		||||
  } else {
 | 
			
		||||
    this.insert(doc, commandOptions, callback && function (err, docs) {
 | 
			
		||||
      if(err) return callback(err, null);
 | 
			
		||||
 | 
			
		||||
      if(Array.isArray(docs)) {
 | 
			
		||||
        callback(err, docs[0]);
 | 
			
		||||
      } else {
 | 
			
		||||
        callback(err, docs);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// ***************************************************
 | 
			
		||||
// Update document function
 | 
			
		||||
// ***************************************************
 | 
			
		||||
var updateWithWriteCommands = function(self, selector, document, options, callback) {
 | 
			
		||||
  if('function' === typeof options) callback = options, options = null;
 | 
			
		||||
  if(options == null) options = {};
 | 
			
		||||
  if(!('function' === typeof callback)) callback = null;
 | 
			
		||||
 | 
			
		||||
  // Get the intended namespace for the operation
 | 
			
		||||
  var namespace = self.collectionName;
 | 
			
		||||
 | 
			
		||||
  // Ensure we have no \x00 bytes in the name causing wrong parsing
 | 
			
		||||
  if(!!~namespace.indexOf("\x00")) {
 | 
			
		||||
    return callback(new Error("namespace cannot contain a null character"), null);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // If we are not providing a selector or document throw
 | 
			
		||||
  if(selector == null || typeof selector != 'object') 
 | 
			
		||||
    return callback(new Error("selector must be a valid JavaScript object"));
 | 
			
		||||
  if(document == null || typeof document != 'object') 
 | 
			
		||||
    return callback(new Error("document must be a valid JavaScript object"));    
 | 
			
		||||
 | 
			
		||||
  // Check if we have passed in continue on error
 | 
			
		||||
  var continueOnError = typeof options['keepGoing'] == 'boolean' 
 | 
			
		||||
    ? options['keepGoing'] : false;
 | 
			
		||||
  continueOnError = typeof options['continueOnError'] == 'boolean' 
 | 
			
		||||
    ? options['continueOnError'] : continueOnError;
 | 
			
		||||
 | 
			
		||||
  // Do we serialzie functions
 | 
			
		||||
  var serializeFunctions = typeof options.serializeFunctions != 'boolean' 
 | 
			
		||||
    ? self.serializeFunctions : options.serializeFunctions;
 | 
			
		||||
 | 
			
		||||
  // Checkout a write connection
 | 
			
		||||
  var connection = self.db.serverConfig.checkoutWriter();  
 | 
			
		||||
  if(connection instanceof Error && connection.code == -5000) return callback(connection);
 | 
			
		||||
 | 
			
		||||
  // Figure out the value of top
 | 
			
		||||
  var multi = typeof options.multi == 'boolean' ? options.multi : false;
 | 
			
		||||
  var upsert = typeof options.upsert == 'boolean' ? options.upsert : false;
 | 
			
		||||
 | 
			
		||||
  // Do we return the actual result document
 | 
			
		||||
  var fullResult = typeof options.fullResult == 'boolean' ? options.fullResult : false;
 | 
			
		||||
 | 
			
		||||
  // Collect errorOptions
 | 
			
		||||
  var errorOptions = shared._getWriteConcern(self, options);
 | 
			
		||||
 | 
			
		||||
  // If we have a write command with no callback and w:0 fail
 | 
			
		||||
  if(errorOptions.w && errorOptions.w != 0 && callback == null) {
 | 
			
		||||
    throw new Error("writeConcern requires callback")
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Create the write command
 | 
			
		||||
  var write_command = {
 | 
			
		||||
    update: namespace,
 | 
			
		||||
    writeConcern: errorOptions,
 | 
			
		||||
    ordered: !continueOnError,
 | 
			
		||||
    updates: [{
 | 
			
		||||
      q : selector,
 | 
			
		||||
      u: document,
 | 
			
		||||
      multi: multi,
 | 
			
		||||
      upsert: upsert
 | 
			
		||||
    }]
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Check if we have a checkKeys override
 | 
			
		||||
  var checkKeys = typeof options.checkKeys == 'boolean' ? options.checkKeys : false;
 | 
			
		||||
 | 
			
		||||
  // Execute the write command
 | 
			
		||||
  self.db.command(write_command
 | 
			
		||||
    , { connection:connection
 | 
			
		||||
      , checkKeys: checkKeys
 | 
			
		||||
      , serializeFunctions: serializeFunctions
 | 
			
		||||
      , writeCommand: true }
 | 
			
		||||
    , function(err, result) { 
 | 
			
		||||
      if(errorOptions.w == 0 && typeof callback == 'function') return callback(null, null);
 | 
			
		||||
      if(errorOptions.w == 0) return;
 | 
			
		||||
      if(callback == null) return;
 | 
			
		||||
 | 
			
		||||
      if(errorOptions.w == 0 && typeof callback == 'function') return callback(null, null);
 | 
			
		||||
      if(errorOptions.w == 0) return;
 | 
			
		||||
      if(callback == null) return;
 | 
			
		||||
      if(err != null) {
 | 
			
		||||
        return callback(err, null);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Result has an error
 | 
			
		||||
      if(!result.ok || Array.isArray(result.writeErrors) && result.writeErrors.length > 0) {
 | 
			
		||||
        var error = utils.toError(result.writeErrors[0].errmsg);
 | 
			
		||||
        error.code = result.writeErrors[0].code;
 | 
			
		||||
        error.err = result.writeErrors[0].errmsg;
 | 
			
		||||
        error.message = result.writeErrors[0].errmsg;
 | 
			
		||||
        return callback(error, null);
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      if(fullResult) return callback(null, result);
 | 
			
		||||
      // Backward compatibility format
 | 
			
		||||
      var r = backWardsCompatibiltyResults(result, 'update');
 | 
			
		||||
      // Return the results for a whole batch
 | 
			
		||||
      callback(null, r.n, r)
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var backWardsCompatibiltyResults = function(result, op) {
 | 
			
		||||
  // Upserted
 | 
			
		||||
  var upsertedValue = null;
 | 
			
		||||
  var finalResult = null;
 | 
			
		||||
  var updatedExisting = true;
 | 
			
		||||
 | 
			
		||||
  // We have a single document upserted result
 | 
			
		||||
  if(Array.isArray(result.upserted) || result.upserted != null) {
 | 
			
		||||
    updatedExisting = false;
 | 
			
		||||
    upsertedValue = result.upserted;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Final result
 | 
			
		||||
  if(op == 'remove' || op == 'insert') {
 | 
			
		||||
    finalResult = {ok: true, n: result.n}
 | 
			
		||||
  } else {
 | 
			
		||||
    finalResult = {ok: true, n: result.n, updatedExisting: updatedExisting}
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(upsertedValue != null) finalResult.upserted = upsertedValue;
 | 
			
		||||
  return finalResult;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var handleWriteResults = function handleWriteResults(callback) {
 | 
			
		||||
  return function(err, error) {
 | 
			
		||||
    var documents = error && error.documents;
 | 
			
		||||
    if(!callback) return;
 | 
			
		||||
    // We have an error
 | 
			
		||||
    if(err) return callback(err, null);
 | 
			
		||||
    // If no document something is terribly wrong
 | 
			
		||||
    if(error == null) return callback(utils.toError("MongoDB did not return a response"));
 | 
			
		||||
    // Handle the case where no result was returned
 | 
			
		||||
    if(error != null && documents == null) {
 | 
			
		||||
      if(typeof error.err == 'string') {
 | 
			
		||||
        return callback(utils.toError(error.err));  
 | 
			
		||||
      } else if(typeof error.errmsg == 'string') {
 | 
			
		||||
        return callback(utils.toError(error.errmsg));          
 | 
			
		||||
      } else {
 | 
			
		||||
        return callback(utils.toError("Unknown MongoDB error"));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Handler normal cases
 | 
			
		||||
    if(documents[0].err || documents[0].errmsg) {
 | 
			
		||||
      callback(utils.toError(documents[0]));
 | 
			
		||||
    } else if(documents[0].jnote || documents[0].wtimeout) {
 | 
			
		||||
      callback(utils.toError(documents[0]));
 | 
			
		||||
    } else {
 | 
			
		||||
      callback(err, documents);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var update = function update(selector, document, options, callback) {
 | 
			
		||||
  if('function' === typeof options) callback = options, options = null;
 | 
			
		||||
  if(options == null) options = {};
 | 
			
		||||
  if(!('function' === typeof callback)) callback = null;
 | 
			
		||||
 | 
			
		||||
  // Get a connection
 | 
			
		||||
  var connection = options.connection || this.db.serverConfig.checkoutWriter();
 | 
			
		||||
  if(connection instanceof Error && connection.code == -5000) return callback(connection);
 | 
			
		||||
  var useLegacyOps = options.useLegacyOps == null || options.useLegacyOps == false ? false : true;
 | 
			
		||||
  // If we support write commands let's perform the insert using it  
 | 
			
		||||
  if(!useLegacyOps && hasWriteCommands(connection) && !Buffer.isBuffer(selector) && !Buffer.isBuffer(document)) {
 | 
			
		||||
    return updateWithWriteCommands(this, selector, document, options, callback);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // DbName
 | 
			
		||||
  var dbName = options['dbName'];
 | 
			
		||||
  // If no dbname defined use the db one
 | 
			
		||||
  if(dbName == null) {
 | 
			
		||||
    dbName = this.db.databaseName;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // If we are not providing a selector or document throw
 | 
			
		||||
  if(selector == null || typeof selector != 'object') return callback(new Error("selector must be a valid JavaScript object"));
 | 
			
		||||
  if(document == null || typeof document != 'object') return callback(new Error("document must be a valid JavaScript object"));
 | 
			
		||||
 | 
			
		||||
  // Do we return the actual result document
 | 
			
		||||
  var fullResult = typeof options.fullResult == 'boolean' ? options.fullResult : false;
 | 
			
		||||
 | 
			
		||||
  // Either use override on the function, or go back to default on either the collection
 | 
			
		||||
  // level or db
 | 
			
		||||
  if(options['serializeFunctions'] != null) {
 | 
			
		||||
    options['serializeFunctions'] = options['serializeFunctions'];
 | 
			
		||||
  } else {
 | 
			
		||||
    options['serializeFunctions'] = this.serializeFunctions;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Build the options command
 | 
			
		||||
  var updateCommand = new UpdateCommand(
 | 
			
		||||
      this.db
 | 
			
		||||
    , dbName + "." + this.collectionName
 | 
			
		||||
    , selector
 | 
			
		||||
    , document
 | 
			
		||||
    , options);
 | 
			
		||||
 | 
			
		||||
  var self = this;
 | 
			
		||||
  // Unpack the error options if any
 | 
			
		||||
  var errorOptions = shared._getWriteConcern(this, options);
 | 
			
		||||
  // If safe is defined check for error message
 | 
			
		||||
  if(shared._hasWriteConcern(errorOptions) && typeof callback == 'function') {
 | 
			
		||||
    // Insert options
 | 
			
		||||
    var commandOptions = {};
 | 
			
		||||
    // Set safe option
 | 
			
		||||
    commandOptions['safe'] = errorOptions;
 | 
			
		||||
    // If we have an error option
 | 
			
		||||
    if(typeof errorOptions == 'object') {
 | 
			
		||||
      var keys = Object.keys(errorOptions);
 | 
			
		||||
      for(var i = 0; i < keys.length; i++) {
 | 
			
		||||
        commandOptions[keys[i]] = errorOptions[keys[i]];
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If we have a passed in connection use it
 | 
			
		||||
    if(options.connection) {
 | 
			
		||||
      commandOptions.connection = options.connection;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Execute command with safe options (rolls up both command and safe command into one and executes them on the same connection)
 | 
			
		||||
    this.db._executeUpdateCommand(updateCommand, commandOptions, handleWriteResults(function(err, results) {
 | 
			
		||||
      if(err) return callback(err, null);
 | 
			
		||||
      if(results == null) return callback(new Error("command failed to return result"));
 | 
			
		||||
      if(fullResult) return callback(null, results);
 | 
			
		||||
      callback(null, results[0].n, results[0]);
 | 
			
		||||
    }));
 | 
			
		||||
  } else if(shared._hasWriteConcern(errorOptions) && callback == null) {
 | 
			
		||||
    throw new Error("Cannot use a writeConcern without a provided callback");
 | 
			
		||||
  } else {
 | 
			
		||||
    // Execute update
 | 
			
		||||
    var result = this.db._executeUpdateCommand(updateCommand);
 | 
			
		||||
    // If no callback just return
 | 
			
		||||
    if (!callback) return;
 | 
			
		||||
    // If error return error
 | 
			
		||||
    if (result instanceof Error) {
 | 
			
		||||
      return callback(result);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Otherwise just return
 | 
			
		||||
    return callback();
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// ***************************************************
 | 
			
		||||
// findAndModify function
 | 
			
		||||
// ***************************************************
 | 
			
		||||
var findAndModify = function findAndModify (query, sort, doc, options, callback) {
 | 
			
		||||
  var args = Array.prototype.slice.call(arguments, 1);
 | 
			
		||||
  callback = args.pop();
 | 
			
		||||
  sort = args.length ? args.shift() || [] : [];
 | 
			
		||||
  doc = args.length ? args.shift() : null;
 | 
			
		||||
  options = args.length ? args.shift() || {} : {};
 | 
			
		||||
  var self = this;
 | 
			
		||||
 | 
			
		||||
  var queryObject = {
 | 
			
		||||
     'findandmodify': this.collectionName
 | 
			
		||||
   , 'query': query
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  sort = utils.formattedOrderClause(sort);
 | 
			
		||||
  if (sort) {
 | 
			
		||||
    queryObject.sort = sort;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  queryObject.new = options.new ? 1 : 0;
 | 
			
		||||
  queryObject.remove = options.remove ? 1 : 0;
 | 
			
		||||
  queryObject.upsert = options.upsert ? 1 : 0;
 | 
			
		||||
 | 
			
		||||
  if (options.fields) {
 | 
			
		||||
    queryObject.fields = options.fields;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (doc && !options.remove) {
 | 
			
		||||
    queryObject.update = doc;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Checkout a write connection
 | 
			
		||||
  options.connection = self.db.serverConfig.checkoutWriter();  
 | 
			
		||||
  if(options.connection instanceof Error && options.connection.code == -5000) return callback(options.connection);
 | 
			
		||||
 | 
			
		||||
  // Either use override on the function, or go back to default on either the collection
 | 
			
		||||
  // level or db
 | 
			
		||||
  if(options['serializeFunctions'] != null) {
 | 
			
		||||
    options['serializeFunctions'] = options['serializeFunctions'];
 | 
			
		||||
  } else {
 | 
			
		||||
    options['serializeFunctions'] = this.serializeFunctions;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // No check on the documents
 | 
			
		||||
  options.checkKeys = false;
 | 
			
		||||
 | 
			
		||||
  // Execute the command
 | 
			
		||||
  this.db.command(queryObject
 | 
			
		||||
    , options, function(err, result) {
 | 
			
		||||
      if(err) return callback(err, null);
 | 
			
		||||
      return callback(null, result.value, result);
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ***************************************************
 | 
			
		||||
// findAndRemove function
 | 
			
		||||
// ***************************************************
 | 
			
		||||
var findAndRemove = function(query, sort, options, callback) {
 | 
			
		||||
  var args = Array.prototype.slice.call(arguments, 1);
 | 
			
		||||
  callback = args.pop();
 | 
			
		||||
  sort = args.length ? args.shift() || [] : [];
 | 
			
		||||
  options = args.length ? args.shift() || {} : {};
 | 
			
		||||
  // Add the remove option
 | 
			
		||||
  options['remove'] = true;
 | 
			
		||||
  // Execute the callback
 | 
			
		||||
  this.findAndModify(query, sort, null, options, callback);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Map methods
 | 
			
		||||
exports.insert = insert;
 | 
			
		||||
exports.remove = remove;
 | 
			
		||||
exports.save = save;
 | 
			
		||||
exports.update = update;
 | 
			
		||||
exports.findAndModify = findAndModify;
 | 
			
		||||
exports.findAndRemove = findAndRemove;
 | 
			
		||||
							
								
								
									
										78
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/collection/geo.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										78
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/collection/geo.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,78 @@
 | 
			
		||||
var shared = require('./shared')
 | 
			
		||||
  , utils = require('../utils');
 | 
			
		||||
 | 
			
		||||
var geoNear = function geoNear(x, y, options, callback) {
 | 
			
		||||
  var point = typeof(x) == 'object' && x
 | 
			
		||||
    , args = Array.prototype.slice.call(arguments, point?1:2);
 | 
			
		||||
 | 
			
		||||
  callback = args.pop();
 | 
			
		||||
  // Fetch all commands
 | 
			
		||||
  options = args.length ? args.shift() || {} : {};
 | 
			
		||||
 | 
			
		||||
  // Build command object
 | 
			
		||||
  var commandObject = {
 | 
			
		||||
    geoNear:this.collectionName,
 | 
			
		||||
    near: point || [x, y]
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Ensure we have the right read preference inheritance
 | 
			
		||||
  options.readPreference = shared._getReadConcern(this, options);
 | 
			
		||||
 | 
			
		||||
  // Exclude readPreference and existing options to prevent user from
 | 
			
		||||
  // shooting themselves in the foot
 | 
			
		||||
  var exclude = {
 | 
			
		||||
    readPreference: true,
 | 
			
		||||
    geoNear: true,
 | 
			
		||||
    near: true
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  commandObject = utils.decorateCommand(commandObject, options, exclude);
 | 
			
		||||
 | 
			
		||||
  // Execute the command
 | 
			
		||||
  this.db.command(commandObject, options, function (err, res) {
 | 
			
		||||
    if (err) {
 | 
			
		||||
      callback(err);
 | 
			
		||||
    } else if (res.err || res.errmsg) {
 | 
			
		||||
      callback(utils.toError(res));
 | 
			
		||||
    } else {
 | 
			
		||||
      // should we only be returning res.results here? Not sure if the user
 | 
			
		||||
      // should see the other return information
 | 
			
		||||
      callback(null, res);
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var geoHaystackSearch = function geoHaystackSearch(x, y, options, callback) {
 | 
			
		||||
  var args = Array.prototype.slice.call(arguments, 2);
 | 
			
		||||
  callback = args.pop();
 | 
			
		||||
  // Fetch all commands
 | 
			
		||||
  options = args.length ? args.shift() || {} : {};
 | 
			
		||||
 | 
			
		||||
  // Build command object
 | 
			
		||||
  var commandObject = {
 | 
			
		||||
    geoSearch:this.collectionName,
 | 
			
		||||
    near: [x, y]
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Remove read preference from hash if it exists
 | 
			
		||||
  commandObject = utils.decorateCommand(commandObject, options, {readPreference: true});
 | 
			
		||||
 | 
			
		||||
  // Ensure we have the right read preference inheritance
 | 
			
		||||
  options.readPreference = shared._getReadConcern(this, options);
 | 
			
		||||
 | 
			
		||||
  // Execute the command
 | 
			
		||||
  this.db.command(commandObject, options, function (err, res) {
 | 
			
		||||
    if (err) {
 | 
			
		||||
      callback(err);
 | 
			
		||||
    } else if (res.err || res.errmsg) {
 | 
			
		||||
      callback(utils.toError(res));
 | 
			
		||||
    } else {
 | 
			
		||||
      // should we only be returning res.results here? Not sure if the user
 | 
			
		||||
      // should see the other return information
 | 
			
		||||
      callback(null, res);
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.geoNear = geoNear;
 | 
			
		||||
exports.geoHaystackSearch = geoHaystackSearch;
 | 
			
		||||
							
								
								
									
										98
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/collection/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										98
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/collection/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,98 @@
 | 
			
		||||
var utils = require('../utils')
 | 
			
		||||
  , CommandCursor = require('../command_cursor').CommandCursor;
 | 
			
		||||
 | 
			
		||||
var _getWriteConcern = require('./shared')._getWriteConcern;
 | 
			
		||||
 | 
			
		||||
var createIndex = function createIndex (fieldOrSpec, options, callback) {
 | 
			
		||||
  // Clean up call
 | 
			
		||||
  var args = Array.prototype.slice.call(arguments, 1);
 | 
			
		||||
  callback = args.pop();
 | 
			
		||||
  options = args.length ? args.shift() || {} : {};
 | 
			
		||||
  options = typeof callback === 'function' ? options : callback;
 | 
			
		||||
  options = options == null ? {} : options;
 | 
			
		||||
 | 
			
		||||
  // Collect errorOptions
 | 
			
		||||
  var errorOptions = _getWriteConcern(this, options);
 | 
			
		||||
  // Execute create index
 | 
			
		||||
  this.db.createIndex(this.collectionName, fieldOrSpec, options, callback);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var indexExists = function indexExists(indexes, callback) {
 | 
			
		||||
 this.indexInformation(function(err, indexInformation) {
 | 
			
		||||
   // If we have an error return
 | 
			
		||||
   if(err != null) return callback(err, null);
 | 
			
		||||
   // Let's check for the index names
 | 
			
		||||
   if(Array.isArray(indexes)) {
 | 
			
		||||
     for(var i = 0; i < indexes.length; i++) {
 | 
			
		||||
       if(indexInformation[indexes[i]] == null) {
 | 
			
		||||
         return callback(null, false);
 | 
			
		||||
       }
 | 
			
		||||
     }
 | 
			
		||||
 | 
			
		||||
     // All keys found return true
 | 
			
		||||
     return callback(null, true);
 | 
			
		||||
   } else {
 | 
			
		||||
     return callback(null, indexInformation[indexes] != null);
 | 
			
		||||
   }
 | 
			
		||||
 });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var dropAllIndexes = function dropIndexes (callback) {
 | 
			
		||||
  this.db.dropIndex(this.collectionName, '*', function (err, result) {
 | 
			
		||||
    if(err) return callback(err, false);
 | 
			
		||||
    callback(null, true);
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var indexInformation = function indexInformation (options, callback) {
 | 
			
		||||
  // Unpack calls
 | 
			
		||||
  var args = Array.prototype.slice.call(arguments, 0);
 | 
			
		||||
  callback = args.pop();
 | 
			
		||||
  options = args.length ? args.shift() || {} : {};
 | 
			
		||||
  // Call the index information
 | 
			
		||||
  this.db.indexInformation(this.collectionName, options, callback);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var ensureIndex = function ensureIndex (fieldOrSpec, options, callback) {
 | 
			
		||||
  // Clean up call
 | 
			
		||||
  if (typeof callback === 'undefined' && typeof options === 'function') {
 | 
			
		||||
    callback = options;
 | 
			
		||||
    options = {};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (options == null) {
 | 
			
		||||
    options = {};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Execute create index
 | 
			
		||||
  this.db.ensureIndex(this.collectionName, fieldOrSpec, options, callback);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var listIndexes = function listIndexes(options) {
 | 
			
		||||
  options = options || {};
 | 
			
		||||
  // Clone the options
 | 
			
		||||
  options = utils.shallowObjectCopy(options);
 | 
			
		||||
 | 
			
		||||
  // Checkout the writer
 | 
			
		||||
  var connection = this.db.serverConfig.checkoutReader();
 | 
			
		||||
 | 
			
		||||
  // We have a list collections command
 | 
			
		||||
  if(connection && connection.serverCapabilities && connection.serverCapabilities.hasListIndexesCommand) {
 | 
			
		||||
    // Cursor options
 | 
			
		||||
    var cursor = options.batchSize ? {batchSize: options.batchSize} : {}
 | 
			
		||||
    // Build the command
 | 
			
		||||
    var command = { listIndexes: this.collectionName, cursor: cursor };
 | 
			
		||||
    // Get the command cursor
 | 
			
		||||
    return new CommandCursor(this.db, this.db.databaseName + ".$cmd", command);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var collection = this.db.collection('system.indexes');
 | 
			
		||||
  return collection.find({ns: this.db.databaseName + "." + this.collectionName});
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
exports.createIndex = createIndex;
 | 
			
		||||
exports.indexExists = indexExists;
 | 
			
		||||
exports.dropAllIndexes = dropAllIndexes;
 | 
			
		||||
exports.indexInformation = indexInformation;
 | 
			
		||||
exports.ensureIndex = ensureIndex;
 | 
			
		||||
exports.listIndexes = listIndexes;
 | 
			
		||||
							
								
								
									
										218
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/collection/query.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										218
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/collection/query.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,218 @@
 | 
			
		||||
var ObjectID = require('bson').ObjectID
 | 
			
		||||
  , Long = require('bson').Long
 | 
			
		||||
  , DbCommand = require('../commands/db_command').DbCommand
 | 
			
		||||
  , CommandCursor = require('../command_cursor').CommandCursor
 | 
			
		||||
  , Scope = require('../scope').Scope
 | 
			
		||||
  , shared = require('./shared')
 | 
			
		||||
  , utils = require('../utils');
 | 
			
		||||
 | 
			
		||||
var testForFields = {
 | 
			
		||||
    limit: 1, sort: 1, fields:1, skip: 1, hint: 1, explain: 1, snapshot: 1, timeout: 1, tailable: 1, tailableRetryInterval: 1
 | 
			
		||||
  , numberOfRetries: 1, awaitdata: 1, exhaust: 1, batchSize: 1, returnKey: 1, maxScan: 1, min: 1, max: 1, showDiskLoc: 1
 | 
			
		||||
  , comment: 1, raw: 1, readPreference: 1, partial: 1, read: 1, dbName: 1, oplogReplay: 1, connection: 1, maxTimeMS: 1, transforms:1
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Find method
 | 
			
		||||
//
 | 
			
		||||
var find = function find () {
 | 
			
		||||
  var options
 | 
			
		||||
    , args = Array.prototype.slice.call(arguments, 0)
 | 
			
		||||
    , has_callback = typeof args[args.length - 1] === 'function'
 | 
			
		||||
    , has_weird_callback = typeof args[0] === 'function'
 | 
			
		||||
    , callback = has_callback ? args.pop() : (has_weird_callback ? args.shift() : null)
 | 
			
		||||
    , len = args.length
 | 
			
		||||
    , selector = len >= 1 ? args[0] : {}
 | 
			
		||||
    , fields = len >= 2 ? args[1] : undefined;
 | 
			
		||||
 | 
			
		||||
  if(len === 1 && has_weird_callback) {
 | 
			
		||||
    // backwards compat for callback?, options case
 | 
			
		||||
    selector = {};
 | 
			
		||||
    options = args[0];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(len === 2 && !Array.isArray(fields)) {
 | 
			
		||||
    var fieldKeys = Object.keys(fields);
 | 
			
		||||
    var is_option = false;
 | 
			
		||||
 | 
			
		||||
    for(var i = 0; i < fieldKeys.length; i++) {
 | 
			
		||||
      if(testForFields[fieldKeys[i]] != null) {
 | 
			
		||||
        is_option = true;
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(is_option) {
 | 
			
		||||
      options = fields;
 | 
			
		||||
      fields = undefined;
 | 
			
		||||
    } else {
 | 
			
		||||
      options = {};
 | 
			
		||||
    }
 | 
			
		||||
  } else if(len === 2 && Array.isArray(fields) && !Array.isArray(fields[0])) {
 | 
			
		||||
    var newFields = {};
 | 
			
		||||
    // Rewrite the array
 | 
			
		||||
    for(var i = 0; i < fields.length; i++) {
 | 
			
		||||
      newFields[fields[i]] = 1;
 | 
			
		||||
    }
 | 
			
		||||
    // Set the fields
 | 
			
		||||
    fields = newFields;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(3 === len) {
 | 
			
		||||
    options = args[2];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Ensure selector is not null
 | 
			
		||||
  selector = selector == null ? {} : selector;
 | 
			
		||||
  // Validate correctness off the selector
 | 
			
		||||
  var object = selector;
 | 
			
		||||
  if(Buffer.isBuffer(object)) {
 | 
			
		||||
    var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24;
 | 
			
		||||
    if(object_size != object.length)  {
 | 
			
		||||
      var error = new Error("query selector raw message size does not match message header size [" + object.length + "] != [" + object_size + "]");
 | 
			
		||||
      error.name = 'MongoError';
 | 
			
		||||
      throw error;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Validate correctness of the field selector
 | 
			
		||||
  var object = fields;
 | 
			
		||||
  if(Buffer.isBuffer(object)) {
 | 
			
		||||
    var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24;
 | 
			
		||||
    if(object_size != object.length)  {
 | 
			
		||||
      var error = new Error("query fields raw message size does not match message header size [" + object.length + "] != [" + object_size + "]");
 | 
			
		||||
      error.name = 'MongoError';
 | 
			
		||||
      throw error;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Check special case where we are using an objectId
 | 
			
		||||
  if(selector instanceof ObjectID || (selector != null && selector._bsontype == 'ObjectID')) {
 | 
			
		||||
    selector = {_id:selector};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // If it's a serialized fields field we need to just let it through
 | 
			
		||||
  // user be warned it better be good
 | 
			
		||||
  if(options && options.fields && !(Buffer.isBuffer(options.fields))) {
 | 
			
		||||
    fields = {};
 | 
			
		||||
 | 
			
		||||
    if(Array.isArray(options.fields)) {
 | 
			
		||||
      if(!options.fields.length) {
 | 
			
		||||
        fields['_id'] = 1;
 | 
			
		||||
      } else {
 | 
			
		||||
        for (var i = 0, l = options.fields.length; i < l; i++) {
 | 
			
		||||
          fields[options.fields[i]] = 1;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      fields = options.fields;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (!options) options = {};
 | 
			
		||||
 | 
			
		||||
  var newOptions = {};
 | 
			
		||||
  // Make a shallow copy of options
 | 
			
		||||
  for (var key in options) {
 | 
			
		||||
    newOptions[key] = options[key];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  newOptions.skip = len > 3 ? args[2] : options.skip ? options.skip : 0;
 | 
			
		||||
  newOptions.limit = len > 3 ? args[3] : options.limit ? options.limit : 0;
 | 
			
		||||
  newOptions.raw = options.raw != null && typeof options.raw === 'boolean' ? options.raw : this.raw;
 | 
			
		||||
  newOptions.hint = options.hint != null ? shared.normalizeHintField(options.hint) : this.internalHint;
 | 
			
		||||
  newOptions.timeout = len == 5 ? args[4] : typeof options.timeout === 'undefined' ? undefined : options.timeout;
 | 
			
		||||
  // If we have overridden slaveOk otherwise use the default db setting
 | 
			
		||||
  newOptions.slaveOk = options.slaveOk != null ? options.slaveOk : this.db.slaveOk;
 | 
			
		||||
 | 
			
		||||
  // Set option
 | 
			
		||||
  var o = newOptions;
 | 
			
		||||
  // Support read/readPreference
 | 
			
		||||
  if(o["read"] != null) o["readPreference"] = o["read"];
 | 
			
		||||
  // If no readPreference specified set the collection level readPreference
 | 
			
		||||
  o.readPreference = o.readPreference ? o.readPreference : this.readPreference;
 | 
			
		||||
  // If still no readPreference specified set the db level
 | 
			
		||||
  o.readPreference = o.readPreference ? o.readPreference : this.db.options.readPreference;
 | 
			
		||||
  // Set slaveok if needed
 | 
			
		||||
  if(o.readPreference == "secondary" || o.read == "secondaryOnly") o.slaveOk = true;
 | 
			
		||||
 | 
			
		||||
  // Ensure the query is an object
 | 
			
		||||
  if(selector != null && typeof selector != 'object') {
 | 
			
		||||
    throw utils.toError("query selector must be an object");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Set the selector
 | 
			
		||||
  o.selector = selector;
 | 
			
		||||
 | 
			
		||||
  // Create precursor
 | 
			
		||||
  var scope = new Scope(this, {}, fields, o);
 | 
			
		||||
  // Callback for backward compatibility
 | 
			
		||||
  if(callback) return callback(null, scope.find(selector));
 | 
			
		||||
  // Return the pre cursor object
 | 
			
		||||
  return scope.find(selector);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var findOne = function findOne () {
 | 
			
		||||
  var self = this;
 | 
			
		||||
  var args = Array.prototype.slice.call(arguments, 0);
 | 
			
		||||
  var callback = args.pop();
 | 
			
		||||
  var cursor = this.find.apply(this, args).limit(-1).batchSize(1);
 | 
			
		||||
 | 
			
		||||
  // Return the item
 | 
			
		||||
  cursor.nextObject(function(err, item) {
 | 
			
		||||
    if(err != null) return callback(utils.toError(err), null);
 | 
			
		||||
    callback(null, item);
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var parallelCollectionScan = function parallelCollectionScan (options, callback) {
 | 
			
		||||
  var self = this;
 | 
			
		||||
 | 
			
		||||
  if(typeof options == 'function') {
 | 
			
		||||
    callback = options;
 | 
			
		||||
    options = {numCursors: 1};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Set number of cursors to 1
 | 
			
		||||
  options.numCursors = options.numCursors || 1;
 | 
			
		||||
  options.batchSize = options.batchSize || 1000;
 | 
			
		||||
 | 
			
		||||
  // Set read preference if we set one
 | 
			
		||||
  options.readPreference = shared._getReadConcern(this, options);
 | 
			
		||||
 | 
			
		||||
  // Create command object
 | 
			
		||||
  var commandObject = {
 | 
			
		||||
      parallelCollectionScan: this.collectionName
 | 
			
		||||
    , numCursors: options.numCursors
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Execute the command
 | 
			
		||||
  this.db.command(commandObject, options, function(err, result) {
 | 
			
		||||
    if(err) return callback(err, null);
 | 
			
		||||
    if(result == null) return callback(new Error("no result returned for parallelCollectionScan"), null);
 | 
			
		||||
 | 
			
		||||
    var cursors = [];
 | 
			
		||||
    // Create command cursors for each item
 | 
			
		||||
    for(var i = 0; i < result.cursors.length; i++) {
 | 
			
		||||
      var rawId = result.cursors[i].cursor.id
 | 
			
		||||
      // Convert cursorId to Long if needed
 | 
			
		||||
      var cursorId = typeof rawId == 'number' ? Long.fromNumber(rawId) : rawId;
 | 
			
		||||
 | 
			
		||||
      // Command cursor options
 | 
			
		||||
      var commandOptions = {
 | 
			
		||||
          batchSize: options.batchSize
 | 
			
		||||
        , cursorId: cursorId
 | 
			
		||||
        , items: result.cursors[i].cursor.firstBatch
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Add a command cursor
 | 
			
		||||
      cursors.push(new CommandCursor(self.db, self, {}, commandOptions));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    callback(null, cursors);
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.find = find;
 | 
			
		||||
exports.findOne = findOne;
 | 
			
		||||
exports.parallelCollectionScan = parallelCollectionScan;
 | 
			
		||||
							
								
								
									
										120
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/collection/shared.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										120
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/collection/shared.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,120 @@
 | 
			
		||||
// ***************************************************
 | 
			
		||||
// Write concerns
 | 
			
		||||
// ***************************************************
 | 
			
		||||
var _hasWriteConcern = function(errorOptions) {
 | 
			
		||||
  return errorOptions == true
 | 
			
		||||
    || errorOptions.w > 0
 | 
			
		||||
    || errorOptions.w == 'majority'
 | 
			
		||||
    || errorOptions.j == true
 | 
			
		||||
    || errorOptions.journal == true
 | 
			
		||||
    || errorOptions.fsync == true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _setWriteConcernHash = function(options) {
 | 
			
		||||
  var finalOptions = {};
 | 
			
		||||
  if(options.w != null) finalOptions.w = options.w;  
 | 
			
		||||
  if(options.journal == true) finalOptions.j = options.journal;
 | 
			
		||||
  if(options.j == true) finalOptions.j = options.j;
 | 
			
		||||
  if(options.fsync == true) finalOptions.fsync = options.fsync;
 | 
			
		||||
  if(options.wtimeout != null) finalOptions.wtimeout = options.wtimeout;  
 | 
			
		||||
  return finalOptions;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _getWriteConcern = function(self, options) {
 | 
			
		||||
  // Final options
 | 
			
		||||
  var finalOptions = {w:1};
 | 
			
		||||
  // Local options verification
 | 
			
		||||
  if(options.w != null || typeof options.j == 'boolean' || typeof options.journal == 'boolean' || typeof options.fsync == 'boolean') {
 | 
			
		||||
    finalOptions = _setWriteConcernHash(options);
 | 
			
		||||
  } else if(typeof options.safe == "boolean") {
 | 
			
		||||
    finalOptions = {w: (options.safe ? 1 : 0)};
 | 
			
		||||
  } else if(options.safe != null && typeof options.safe == 'object') {
 | 
			
		||||
    finalOptions = _setWriteConcernHash(options.safe);
 | 
			
		||||
  } else if(self.opts.w != null || typeof self.opts.j == 'boolean' || typeof self.opts.journal == 'boolean' || typeof self.opts.fsync == 'boolean') {
 | 
			
		||||
    finalOptions = _setWriteConcernHash(self.opts);
 | 
			
		||||
  } else if(typeof self.opts.safe == "boolean") {
 | 
			
		||||
    finalOptions = {w: (self.opts.safe ? 1 : 0)};
 | 
			
		||||
  } else if(self.db.safe.w != null || typeof self.db.safe.j == 'boolean' || typeof self.db.safe.journal == 'boolean' || typeof self.db.safe.fsync == 'boolean') {
 | 
			
		||||
    finalOptions = _setWriteConcernHash(self.db.safe);
 | 
			
		||||
  } else if(self.db.options.w != null || typeof self.db.options.j == 'boolean' || typeof self.db.options.journal == 'boolean' || typeof self.db.options.fsync == 'boolean') {
 | 
			
		||||
    finalOptions = _setWriteConcernHash(self.db.options);
 | 
			
		||||
  } else if(typeof self.db.safe == "boolean") {
 | 
			
		||||
    finalOptions = {w: (self.db.safe ? 1 : 0)};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Ensure we don't have an invalid combination of write concerns
 | 
			
		||||
  if(finalOptions.w < 1 
 | 
			
		||||
    && (finalOptions.journal == true || finalOptions.j == true || finalOptions.fsync == true)) throw new Error("No acknowlegement using w < 1 cannot be combined with journal:true or fsync:true");
 | 
			
		||||
 | 
			
		||||
  // Return the options
 | 
			
		||||
  return finalOptions;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _getReadConcern = function(self, options) {
 | 
			
		||||
  if(options.readPreference) return options.readPreference;
 | 
			
		||||
  if(self.readPreference) return self.readPreference;
 | 
			
		||||
  if(self.db.readPreference) return self.readPreference;
 | 
			
		||||
  return 'primary';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
var checkCollectionName = function checkCollectionName (collectionName) {
 | 
			
		||||
  if('string' !== typeof collectionName) {
 | 
			
		||||
    throw Error("collection name must be a String");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(!collectionName || collectionName.indexOf('..') != -1) {
 | 
			
		||||
    throw Error("collection names cannot be empty");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(collectionName.indexOf('$') != -1 &&
 | 
			
		||||
      collectionName.match(/((^\$cmd)|(oplog\.\$main))/) == null) {
 | 
			
		||||
    throw Error("collection names must not contain '$'");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(collectionName.match(/^\.|\.$/) != null) {
 | 
			
		||||
    throw Error("collection names must not start or end with '.'");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Validate that we are not passing 0x00 in the colletion name
 | 
			
		||||
  if(!!~collectionName.indexOf("\x00")) {
 | 
			
		||||
    throw new Error("collection names cannot contain a null character");
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Normalizes a `hint` argument.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {String|Object|Array} hint
 | 
			
		||||
 * @return {Object}
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
var normalizeHintField = function normalizeHintField(hint) {
 | 
			
		||||
  var finalHint = null;
 | 
			
		||||
 | 
			
		||||
  if(typeof hint == 'string') {
 | 
			
		||||
    finalHint = hint;
 | 
			
		||||
  } else if(Array.isArray(hint)) {
 | 
			
		||||
    finalHint = {};
 | 
			
		||||
 | 
			
		||||
    hint.forEach(function(param) {
 | 
			
		||||
      finalHint[param] = 1;
 | 
			
		||||
    });  
 | 
			
		||||
  } else if(hint != null && typeof hint == 'object') {
 | 
			
		||||
    finalHint = {};
 | 
			
		||||
    for (var name in hint) {
 | 
			
		||||
      finalHint[name] = hint[name];
 | 
			
		||||
    }    
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return finalHint;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
exports._getWriteConcern = _getWriteConcern;
 | 
			
		||||
exports._hasWriteConcern = _hasWriteConcern;
 | 
			
		||||
exports._getReadConcern = _getReadConcern;
 | 
			
		||||
exports.checkCollectionName = checkCollectionName;
 | 
			
		||||
exports.normalizeHintField = normalizeHintField;
 | 
			
		||||
							
								
								
									
										384
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/command_cursor.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										384
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/command_cursor.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,384 @@
 | 
			
		||||
var Long = require('bson').Long
 | 
			
		||||
  , Readable = require('stream').Readable || require('readable-stream').Readable
 | 
			
		||||
  , GetMoreCommand = require('./commands/get_more_command').GetMoreCommand
 | 
			
		||||
  , inherits = require('util').inherits;
 | 
			
		||||
 | 
			
		||||
var CommandCursor = function(db, collection, command, options) {  
 | 
			
		||||
  var self = this;
 | 
			
		||||
  // Ensure empty options if no options passed
 | 
			
		||||
  options = options || {};  
 | 
			
		||||
  
 | 
			
		||||
  // Set up
 | 
			
		||||
  Readable.call(this, {objectMode: true});
 | 
			
		||||
 | 
			
		||||
  // Default cursor id is 0
 | 
			
		||||
  var cursorId = options.cursorId || Long.fromInt(0);
 | 
			
		||||
  var zeroCursor = Long.fromInt(0);
 | 
			
		||||
  var state = 'init';
 | 
			
		||||
  var batchSize = options.batchSize || 0;
 | 
			
		||||
 | 
			
		||||
  // Hardcode batch size
 | 
			
		||||
  if(command && command.cursor) {
 | 
			
		||||
    batchSize = command.cursor.batchSize || 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // BatchSize
 | 
			
		||||
  var raw = options.raw || false;
 | 
			
		||||
  var readPreference = options.readPreference || 'primary';
 | 
			
		||||
 | 
			
		||||
  // Cursor namespace
 | 
			
		||||
  this.ns = db.databaseName + "." + collection.collectionName
 | 
			
		||||
 | 
			
		||||
  // Checkout a connection
 | 
			
		||||
  var connection = db.serverConfig.checkoutReader(readPreference);
 | 
			
		||||
  // MaxTimeMS
 | 
			
		||||
  var maxTimeMS = options.maxTimeMS;
 | 
			
		||||
  var transform = options.transform;
 | 
			
		||||
 | 
			
		||||
  // Contains all the items
 | 
			
		||||
  var items = options.items || null;
 | 
			
		||||
 | 
			
		||||
  // Execute getmore
 | 
			
		||||
  var getMore = function(callback) {
 | 
			
		||||
    // Resolve more of the cursor using the getMore command
 | 
			
		||||
    var getMoreCommand = new GetMoreCommand(db
 | 
			
		||||
      , self.ns
 | 
			
		||||
      , batchSize
 | 
			
		||||
      , cursorId
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // Set up options
 | 
			
		||||
    var command_options = { connection:connection };
 | 
			
		||||
 | 
			
		||||
    // Execute the getMore Command
 | 
			
		||||
    db._executeQueryCommand(getMoreCommand, command_options, function(err, result) {
 | 
			
		||||
      if(err) {
 | 
			
		||||
        items = [];
 | 
			
		||||
        state = 'closed';
 | 
			
		||||
        return callback(err);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Return all the documents
 | 
			
		||||
      callback(null, result);
 | 
			
		||||
    });    
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var exhaustGetMore = function(callback) {
 | 
			
		||||
    getMore(function(err, result) {
 | 
			
		||||
      if(err) {
 | 
			
		||||
        items = [];
 | 
			
		||||
        state = 'closed';
 | 
			
		||||
        return callback(err, null);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Add the items
 | 
			
		||||
      items = items.concat(result.documents);      
 | 
			
		||||
 | 
			
		||||
      // Set the cursor id
 | 
			
		||||
      cursorId = result.cursorId;
 | 
			
		||||
      if(typeof cursorId == 'number') cursorId = Long.fromNumber(cursorId);
 | 
			
		||||
      
 | 
			
		||||
      // If the cursor is done
 | 
			
		||||
      if(result.cursorId.equals(zeroCursor)) {
 | 
			
		||||
        return callback(null, items);
 | 
			
		||||
      } 
 | 
			
		||||
 | 
			
		||||
      // Check the cursor id
 | 
			
		||||
      exhaustGetMore(callback);
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var exhaustGetMoreEach = function(callback) {
 | 
			
		||||
    getMore(function(err, result) {
 | 
			
		||||
      if(err) {
 | 
			
		||||
        items = [];
 | 
			
		||||
        state = 'closed';
 | 
			
		||||
        return callback(err, null);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Add the items
 | 
			
		||||
      items = result.documents;
 | 
			
		||||
 | 
			
		||||
      // Emit all the items in the first batch
 | 
			
		||||
      while(items.length > 0) {
 | 
			
		||||
        callback(null, items.shift());
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      // Set the cursor id
 | 
			
		||||
      cursorId = result.cursorId;
 | 
			
		||||
      if(typeof cursorId == 'number') cursorId = Long.fromNumber(cursorId);
 | 
			
		||||
 | 
			
		||||
      // If the cursor is done
 | 
			
		||||
      if(result.cursorId.equals(zeroCursor)) {
 | 
			
		||||
        state = "closed";
 | 
			
		||||
        return callback(null, null);
 | 
			
		||||
      } 
 | 
			
		||||
      
 | 
			
		||||
      // Check the cursor id
 | 
			
		||||
      exhaustGetMoreEach(callback);
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // Get all the elements
 | 
			
		||||
  //
 | 
			
		||||
  this.get = function(options, callback) {
 | 
			
		||||
    var self = this;
 | 
			
		||||
    if(typeof options == 'function') {
 | 
			
		||||
      callback = options;
 | 
			
		||||
      options = {};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Set the connection to the passed in one if it's provided
 | 
			
		||||
    connection = options.connection ? options.connection : connection;
 | 
			
		||||
 | 
			
		||||
    // Command options
 | 
			
		||||
    var _options = {connection:connection};
 | 
			
		||||
    if(typeof maxTimeMS == 'number') _options.maxTimeMS = maxTimeMS;
 | 
			
		||||
 | 
			
		||||
    // If we have a cursor Id already not equal to 0 we are just going to
 | 
			
		||||
    // exhaust the cursor
 | 
			
		||||
    if(cursorId.notEquals(zeroCursor)) {
 | 
			
		||||
      // If no items set an empty array
 | 
			
		||||
      items = items || [];
 | 
			
		||||
      // Exhaust the cursor
 | 
			
		||||
      return exhaustGetMore(callback);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Execute the internal command first
 | 
			
		||||
    db.command(command, _options, function(err, result) {
 | 
			
		||||
      if(err) {
 | 
			
		||||
        state = 'closed';
 | 
			
		||||
        return callback(err, null);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if(result.cursor && typeof result.cursor.id == 'number') {
 | 
			
		||||
        // Retrieve the cursor id
 | 
			
		||||
        cursorId = result.cursor.id;
 | 
			
		||||
        self.ns = result.cursor.ns;
 | 
			
		||||
        if(typeof cursorId == 'number') cursorId = Long.fromNumber(cursorId);
 | 
			
		||||
 | 
			
		||||
        // Validate cursorId
 | 
			
		||||
        if(cursorId.equals(zeroCursor)) {
 | 
			
		||||
          var docs = typeof transform == 'function' ? transform(result.cursor.firstBatch) : result.cursor.firstBatch;
 | 
			
		||||
          return callback(null, docs);
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // Add to the items
 | 
			
		||||
        items = result.cursor.firstBatch;
 | 
			
		||||
      } else {
 | 
			
		||||
        cursorId = zeroCursor;
 | 
			
		||||
        var docs = typeof transform == 'function' ? transform(items) : items;
 | 
			
		||||
        items = [];
 | 
			
		||||
        return callback(null, items);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Execute the getMore
 | 
			
		||||
      exhaustGetMore(callback);
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.toArray = this.get;
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // Iterate over all the items
 | 
			
		||||
  //
 | 
			
		||||
  this.each = function(options, callback) {
 | 
			
		||||
    var self = this;
 | 
			
		||||
    if(typeof options == 'function') {
 | 
			
		||||
      callback = options;
 | 
			
		||||
      options = {};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If it's a closed cursor return error
 | 
			
		||||
    if(this.isClosed()) return callback(new Error("cursor is closed"));
 | 
			
		||||
    // Set the connection to the passed in one if it's provided
 | 
			
		||||
    connection = options.connection ? options.connection : connection;
 | 
			
		||||
  
 | 
			
		||||
    // Command options
 | 
			
		||||
    var _options = {connection:connection};
 | 
			
		||||
    if(typeof maxTimeMS == 'number') _options.maxTimeMS = maxTimeMS;
 | 
			
		||||
 | 
			
		||||
    // If we have a cursor Id already not equal to 0 we are just going to
 | 
			
		||||
    // exhaust the cursor
 | 
			
		||||
    if(cursorId.notEquals(zeroCursor)) {
 | 
			
		||||
      // If no items set an empty array
 | 
			
		||||
      items = items || [];
 | 
			
		||||
 | 
			
		||||
      // Emit all the items in the first batch
 | 
			
		||||
      while(items.length > 0) {
 | 
			
		||||
        callback(null, items.shift());
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Exhaust the cursor
 | 
			
		||||
      return exhaustGetMoreEach(callback);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Execute the internal command first
 | 
			
		||||
    db.command(command, _options, function(err, result) {
 | 
			
		||||
      if(err) {
 | 
			
		||||
        state = 'closed';
 | 
			
		||||
        return callback(err, null);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Get all the items
 | 
			
		||||
      items = result.cursor.firstBatch;
 | 
			
		||||
 | 
			
		||||
      // Emit all the items in the first batch
 | 
			
		||||
      while(items.length > 0) {
 | 
			
		||||
        callback(null, items.shift());
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Retrieve the cursor id
 | 
			
		||||
      cursorId = result.cursor.id;
 | 
			
		||||
      self.ns = result.cursor.ns;
 | 
			
		||||
      if(typeof cursorId == 'number') cursorId = Long.fromNumber(cursorId);
 | 
			
		||||
 | 
			
		||||
      // If no cursor we just finish up the current batch of items
 | 
			
		||||
      if(cursorId.equals(zeroCursor)) {
 | 
			
		||||
        state = 'closed';        
 | 
			
		||||
        return callback(null, null);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Emit each until no more getMore's
 | 
			
		||||
      exhaustGetMoreEach(callback);
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // Get the next object
 | 
			
		||||
  //
 | 
			
		||||
  this.next = function(options, callback) {
 | 
			
		||||
    var self = this;
 | 
			
		||||
    if(typeof options == 'function') {
 | 
			
		||||
      callback = options;
 | 
			
		||||
      options = {};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If it's a closed cursor return error
 | 
			
		||||
    if(this.isClosed()) return callback(new Error("cursor is closed"));
 | 
			
		||||
 | 
			
		||||
    // Set the connection to the passed in one if it's provided
 | 
			
		||||
    connection = options.connection ? options.connection : connection;
 | 
			
		||||
  
 | 
			
		||||
    // Command options
 | 
			
		||||
    var _options = {connection:connection};
 | 
			
		||||
    if(typeof maxTimeMS == 'number') _options.maxTimeMS = maxTimeMS;
 | 
			
		||||
 | 
			
		||||
    // If we have a cursor Id already not equal to 0 we are just going to
 | 
			
		||||
    // going to bypass the command execution
 | 
			
		||||
    if(cursorId.notEquals(zeroCursor)) {
 | 
			
		||||
      items = items || [];
 | 
			
		||||
    }    
 | 
			
		||||
 | 
			
		||||
    // Execute the internal command first
 | 
			
		||||
    if(!items) {
 | 
			
		||||
      db.command(command, _options, function(err, result) {
 | 
			
		||||
        if(err) {
 | 
			
		||||
          state = 'closed';
 | 
			
		||||
          return callback(err, null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Retrieve the cursor id
 | 
			
		||||
        cursorId = result.cursor.id;
 | 
			
		||||
        self.ns = result.cursor.ns;
 | 
			
		||||
        if(typeof cursorId == 'number') cursorId = Long.fromNumber(cursorId);
 | 
			
		||||
        // Get the first batch results
 | 
			
		||||
        items = result.cursor.firstBatch;
 | 
			
		||||
        // We have items return the first one
 | 
			
		||||
        if(items.length > 0) {
 | 
			
		||||
          callback(null, items.shift());
 | 
			
		||||
        } else {
 | 
			
		||||
          state = 'closed';
 | 
			
		||||
          callback(null, null);
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
    } else if(items.length > 0) {
 | 
			
		||||
      callback(null, items.shift());
 | 
			
		||||
    } else if(items.length == 0 && cursorId.equals(zeroCursor)) {
 | 
			
		||||
      state = 'closed';
 | 
			
		||||
      callback(null, null);
 | 
			
		||||
    } else {
 | 
			
		||||
      // Execute a getMore
 | 
			
		||||
      getMore(function(err, result) {
 | 
			
		||||
        if(err) {
 | 
			
		||||
          state = 'closed';
 | 
			
		||||
          return callback(err, null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Set the cursor id
 | 
			
		||||
        cursorId = result.cursorId;
 | 
			
		||||
        if(typeof cursorId == 'number') cursorId = Long.fromNumber(cursorId);
 | 
			
		||||
 | 
			
		||||
        // Add the items
 | 
			
		||||
        items = items.concat(result.documents);
 | 
			
		||||
        // If no more items
 | 
			
		||||
        if(items.length == 0) {
 | 
			
		||||
          state = 'closed';
 | 
			
		||||
          return callback(null, null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Return the item
 | 
			
		||||
        return callback(null, items.shift());
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Validate if the cursor is closed
 | 
			
		||||
  this.isClosed = function() {
 | 
			
		||||
    return state == 'closed';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Allow us to set the MaxTimeMS
 | 
			
		||||
  this.maxTimeMS = function(_maxTimeMS) {
 | 
			
		||||
    maxTimeMS = _maxTimeMS;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Close the cursor sending a kill cursor command if needed
 | 
			
		||||
  this.close = function(callback) {
 | 
			
		||||
    // Close the cursor if not needed
 | 
			
		||||
    if(cursorId instanceof Long && cursorId.greaterThan(Long.fromInt(0))) {
 | 
			
		||||
      try {
 | 
			
		||||
        var command = new KillCursorCommand(this.db, [cursorId]);
 | 
			
		||||
        // Added an empty callback to ensure we don't throw any null exceptions
 | 
			
		||||
        db._executeQueryCommand(command, {connection:connection});
 | 
			
		||||
      } catch(err) {}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Null out the connection
 | 
			
		||||
    connection = null;
 | 
			
		||||
    // Reset cursor id
 | 
			
		||||
    cursorId = Long.fromInt(0);
 | 
			
		||||
    // Set to closed status
 | 
			
		||||
    state = 'closed';
 | 
			
		||||
    // Clear out all the items
 | 
			
		||||
    items = null;
 | 
			
		||||
 | 
			
		||||
    if(callback) {
 | 
			
		||||
      callback(null, null);
 | 
			
		||||
    }    
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // Stream method
 | 
			
		||||
  //
 | 
			
		||||
  this._read = function(n) {
 | 
			
		||||
    var self = this;
 | 
			
		||||
    // Read the next command cursor doc
 | 
			
		||||
    self.next(function(err, result) {
 | 
			
		||||
      if(err) {
 | 
			
		||||
        self.emit('error', err);
 | 
			
		||||
        return self.push(null);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      self.push(result);
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Inherit from Readable
 | 
			
		||||
if(Readable != null) {
 | 
			
		||||
  inherits(CommandCursor, Readable);  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.CommandCursor = CommandCursor;
 | 
			
		||||
							
								
								
									
										29
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/commands/base_command.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										29
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/commands/base_command.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
/**
 | 
			
		||||
  Base object used for common functionality
 | 
			
		||||
**/
 | 
			
		||||
var BaseCommand = exports.BaseCommand = function BaseCommand() {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var id = 1;
 | 
			
		||||
BaseCommand.prototype.getRequestId = function getRequestId() {
 | 
			
		||||
  if (!this.requestId) this.requestId = id++;
 | 
			
		||||
  return this.requestId;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
BaseCommand.prototype.setMongosReadPreference = function setMongosReadPreference(readPreference, tags) {}
 | 
			
		||||
 | 
			
		||||
BaseCommand.prototype.updateRequestId = function() {
 | 
			
		||||
  this.requestId = id++;
 | 
			
		||||
  return this.requestId;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// OpCodes
 | 
			
		||||
BaseCommand.OP_REPLY = 1;
 | 
			
		||||
BaseCommand.OP_MSG = 1000;
 | 
			
		||||
BaseCommand.OP_UPDATE = 2001;
 | 
			
		||||
BaseCommand.OP_INSERT =	2002;
 | 
			
		||||
BaseCommand.OP_GET_BY_OID = 2003;
 | 
			
		||||
BaseCommand.OP_QUERY = 2004;
 | 
			
		||||
BaseCommand.OP_GET_MORE = 2005;
 | 
			
		||||
BaseCommand.OP_DELETE =	2006;
 | 
			
		||||
BaseCommand.OP_KILL_CURSORS =	2007;
 | 
			
		||||
							
								
								
									
										101
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/commands/db_command.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										101
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/commands/db_command.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,101 @@
 | 
			
		||||
var QueryCommand = require('./query_command').QueryCommand,
 | 
			
		||||
  InsertCommand = require('./insert_command').InsertCommand,
 | 
			
		||||
  inherits = require('util').inherits,
 | 
			
		||||
  utils = require('../utils'),
 | 
			
		||||
  crypto = require('crypto');
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Db Command
 | 
			
		||||
**/
 | 
			
		||||
var DbCommand = exports.DbCommand = function(dbInstance, collectionName, queryOptions, numberToSkip, numberToReturn, query, returnFieldSelector, options) {
 | 
			
		||||
  QueryCommand.call(this);
 | 
			
		||||
  this.collectionName = collectionName;
 | 
			
		||||
  this.queryOptions = queryOptions;
 | 
			
		||||
  this.numberToSkip = numberToSkip;
 | 
			
		||||
  this.numberToReturn = numberToReturn;
 | 
			
		||||
  this.query = query;
 | 
			
		||||
  this.returnFieldSelector = returnFieldSelector;
 | 
			
		||||
  this.db = dbInstance;
 | 
			
		||||
 | 
			
		||||
  // Set the slave ok bit
 | 
			
		||||
  if(this.db && this.db.slaveOk) {
 | 
			
		||||
    this.queryOptions |= QueryCommand.OPTS_SLAVE;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Make sure we don't get a null exception
 | 
			
		||||
  options = options == null ? {} : options;
 | 
			
		||||
 | 
			
		||||
  // Allow for overriding the BSON checkKeys function
 | 
			
		||||
  this.checkKeys = typeof options['checkKeys'] == 'boolean' ? options["checkKeys"] : true;
 | 
			
		||||
 | 
			
		||||
  // Let us defined on a command basis if we want functions to be serialized or not
 | 
			
		||||
  if(options['serializeFunctions'] != null && options['serializeFunctions']) {
 | 
			
		||||
    this.serializeFunctions = true;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inherits(DbCommand, QueryCommand);
 | 
			
		||||
 | 
			
		||||
// Constants
 | 
			
		||||
DbCommand.SYSTEM_NAMESPACE_COLLECTION = "system.namespaces";
 | 
			
		||||
DbCommand.SYSTEM_INDEX_COLLECTION = "system.indexes";
 | 
			
		||||
DbCommand.SYSTEM_PROFILE_COLLECTION = "system.profile";
 | 
			
		||||
DbCommand.SYSTEM_USER_COLLECTION = "system.users";
 | 
			
		||||
DbCommand.SYSTEM_COMMAND_COLLECTION = "$cmd";
 | 
			
		||||
DbCommand.SYSTEM_JS_COLLECTION = "system.js";
 | 
			
		||||
 | 
			
		||||
// New commands
 | 
			
		||||
DbCommand.NcreateIsMasterCommand = function(db, databaseName) {
 | 
			
		||||
  return new DbCommand(db, databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'ismaster':1}, null);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Provide constructors for different db commands
 | 
			
		||||
DbCommand.createIsMasterCommand = function(db) {
 | 
			
		||||
  return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'ismaster':1}, null);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
DbCommand.createGetLastErrorCommand = function(options, db) {
 | 
			
		||||
  if (typeof db === 'undefined') {
 | 
			
		||||
    db =  options;
 | 
			
		||||
    options = {};
 | 
			
		||||
  }
 | 
			
		||||
  // Final command
 | 
			
		||||
  var command = {'getlasterror':1};
 | 
			
		||||
  // If we have an options Object let's merge in the fields (fsync/wtimeout/w)
 | 
			
		||||
  if('object' === typeof options) {
 | 
			
		||||
    for(var name in options) {
 | 
			
		||||
      command[name] = options[name]
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Special case for w == 1, remove the w
 | 
			
		||||
  if(1 == command.w) {
 | 
			
		||||
    delete command.w;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Execute command
 | 
			
		||||
  return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command, null);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
DbCommand.createGetLastStatusCommand = DbCommand.createGetLastErrorCommand;
 | 
			
		||||
 | 
			
		||||
DbCommand.createDbCommand = function(db, command_hash, options, auth_db) {
 | 
			
		||||
  var db_name = (auth_db ? auth_db : db.databaseName) + "." + DbCommand.SYSTEM_COMMAND_COLLECTION;
 | 
			
		||||
  options = options == null ? {checkKeys: false} : options;
 | 
			
		||||
  return new DbCommand(db, db_name, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command_hash, null, options);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
DbCommand.createAdminDbCommand = function(db, command_hash) {
 | 
			
		||||
  return new DbCommand(db, "admin." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command_hash, null);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
DbCommand.createAdminDbCommandSlaveOk = function(db, command_hash) {
 | 
			
		||||
  return new DbCommand(db, "admin." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT | QueryCommand.OPTS_SLAVE, 0, -1, command_hash, null);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
DbCommand.createDbSlaveOkCommand = function(db, command_hash, options) {
 | 
			
		||||
  options = options == null ? {checkKeys: false} : options;
 | 
			
		||||
  var dbName = options.dbName ? options.dbName : db.databaseName;
 | 
			
		||||
  var flags = options.slaveOk ? QueryCommand.OPTS_NO_CURSOR_TIMEOUT | QueryCommand.OPTS_SLAVE : QueryCommand.OPTS_NO_CURSOR_TIMEOUT;
 | 
			
		||||
  return new DbCommand(db, dbName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, flags, 0, -1, command_hash, null, options);
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										129
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/commands/delete_command.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										129
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/commands/delete_command.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,129 @@
 | 
			
		||||
var BaseCommand = require('./base_command').BaseCommand,
 | 
			
		||||
  inherits = require('util').inherits;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Insert Document Command
 | 
			
		||||
**/
 | 
			
		||||
var DeleteCommand = exports.DeleteCommand = function(db, collectionName, selector, flags) {
 | 
			
		||||
  BaseCommand.call(this);
 | 
			
		||||
 | 
			
		||||
  // Validate correctness off the selector
 | 
			
		||||
  var object = selector;
 | 
			
		||||
  if(Buffer.isBuffer(object)) {
 | 
			
		||||
    var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24;        
 | 
			
		||||
    if(object_size != object.length)  {
 | 
			
		||||
      var error = new Error("delete raw message size does not match message header size [" + object.length + "] != [" + object_size + "]");
 | 
			
		||||
      error.name = 'MongoError';
 | 
			
		||||
      throw error;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  this.flags = flags;
 | 
			
		||||
  this.collectionName = collectionName;
 | 
			
		||||
  this.selector = selector;
 | 
			
		||||
  this.db = db;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inherits(DeleteCommand, BaseCommand);
 | 
			
		||||
 | 
			
		||||
DeleteCommand.OP_DELETE =	2006;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
struct {
 | 
			
		||||
    MsgHeader header;                 // standard message header
 | 
			
		||||
    int32     ZERO;                   // 0 - reserved for future use
 | 
			
		||||
    cstring   fullCollectionName;     // "dbname.collectionname"
 | 
			
		||||
    int32     ZERO;                   // 0 - reserved for future use
 | 
			
		||||
    mongo.BSON      selector;               // query object.  See below for details.
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
DeleteCommand.prototype.toBinary = function(bsonSettings) {
 | 
			
		||||
  // Validate that we are not passing 0x00 in the colletion name
 | 
			
		||||
  if(!!~this.collectionName.indexOf("\x00")) {
 | 
			
		||||
    throw new Error("namespace cannot contain a null character");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Calculate total length of the document
 | 
			
		||||
  var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + this.db.bson.calculateObjectSize(this.selector, false, true) + (4 * 4);
 | 
			
		||||
  
 | 
			
		||||
  // Enforce maximum bson size
 | 
			
		||||
  if(!bsonSettings.disableDriverBSONSizeCheck 
 | 
			
		||||
    && totalLengthOfCommand > bsonSettings.maxBsonSize) 
 | 
			
		||||
    throw new Error("Document exceeds maximum allowed bson size of " + bsonSettings.maxBsonSize + " bytes");
 | 
			
		||||
 | 
			
		||||
  if(bsonSettings.disableDriverBSONSizeCheck 
 | 
			
		||||
    && totalLengthOfCommand > bsonSettings.maxMessageSizeBytes) 
 | 
			
		||||
    throw new Error("Command exceeds maximum message size of " + bsonSettings.maxMessageSizeBytes + " bytes");
 | 
			
		||||
 | 
			
		||||
  // Let's build the single pass buffer command
 | 
			
		||||
  var _index = 0;
 | 
			
		||||
  var _command = new Buffer(totalLengthOfCommand);
 | 
			
		||||
  // Write the header information to the buffer
 | 
			
		||||
  _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff;     
 | 
			
		||||
  _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff;
 | 
			
		||||
  _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff;
 | 
			
		||||
  _command[_index] = totalLengthOfCommand & 0xff;
 | 
			
		||||
  // Adjust index
 | 
			
		||||
  _index = _index + 4;
 | 
			
		||||
  // Write the request ID
 | 
			
		||||
  _command[_index + 3] = (this.requestId >> 24) & 0xff;     
 | 
			
		||||
  _command[_index + 2] = (this.requestId >> 16) & 0xff;
 | 
			
		||||
  _command[_index + 1] = (this.requestId >> 8) & 0xff;
 | 
			
		||||
  _command[_index] = this.requestId & 0xff;
 | 
			
		||||
  // Adjust index
 | 
			
		||||
  _index = _index + 4;
 | 
			
		||||
  // Write zero
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  // Write the op_code for the command
 | 
			
		||||
  _command[_index + 3] = (DeleteCommand.OP_DELETE >> 24) & 0xff;     
 | 
			
		||||
  _command[_index + 2] = (DeleteCommand.OP_DELETE >> 16) & 0xff;
 | 
			
		||||
  _command[_index + 1] = (DeleteCommand.OP_DELETE >> 8) & 0xff;
 | 
			
		||||
  _command[_index] = DeleteCommand.OP_DELETE & 0xff;
 | 
			
		||||
  // Adjust index
 | 
			
		||||
  _index = _index + 4;
 | 
			
		||||
 | 
			
		||||
  // Write zero
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
 | 
			
		||||
  // Write the collection name to the command
 | 
			
		||||
  _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1;
 | 
			
		||||
  _command[_index - 1] = 0;    
 | 
			
		||||
 | 
			
		||||
  // Write the flags
 | 
			
		||||
  _command[_index + 3] = (this.flags >> 24) & 0xff;     
 | 
			
		||||
  _command[_index + 2] = (this.flags >> 16) & 0xff;
 | 
			
		||||
  _command[_index + 1] = (this.flags >> 8) & 0xff;
 | 
			
		||||
  _command[_index] = this.flags & 0xff;
 | 
			
		||||
  // Adjust index
 | 
			
		||||
  _index = _index + 4;
 | 
			
		||||
 | 
			
		||||
  // Document binary length
 | 
			
		||||
  var documentLength = 0
 | 
			
		||||
 | 
			
		||||
  // Serialize the selector
 | 
			
		||||
  // If we are passing a raw buffer, do minimal validation
 | 
			
		||||
  if(Buffer.isBuffer(this.selector)) {
 | 
			
		||||
    documentLength = this.selector.length;
 | 
			
		||||
    // Copy the data into the current buffer
 | 
			
		||||
    this.selector.copy(_command, _index);
 | 
			
		||||
  } else {
 | 
			
		||||
    documentLength = this.db.bson.serializeWithBufferAndIndex(this.selector, false, _command, _index) - _index + 1;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Write the length to the document
 | 
			
		||||
  _command[_index + 3] = (documentLength >> 24) & 0xff;     
 | 
			
		||||
  _command[_index + 2] = (documentLength >> 16) & 0xff;
 | 
			
		||||
  _command[_index + 1] = (documentLength >> 8) & 0xff;
 | 
			
		||||
  _command[_index] = documentLength & 0xff;
 | 
			
		||||
  // Update index in buffer
 | 
			
		||||
  _index = _index + documentLength;
 | 
			
		||||
  // Add terminating 0 for the object
 | 
			
		||||
  _command[_index - 1] = 0;      
 | 
			
		||||
  return _command;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										88
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/commands/get_more_command.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										88
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/commands/get_more_command.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,88 @@
 | 
			
		||||
var BaseCommand = require('./base_command').BaseCommand,
 | 
			
		||||
  inherits = require('util').inherits,
 | 
			
		||||
  binaryutils = require('../utils');
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Get More Document Command
 | 
			
		||||
**/
 | 
			
		||||
var GetMoreCommand = exports.GetMoreCommand = function(db, collectionName, numberToReturn, cursorId) {
 | 
			
		||||
  BaseCommand.call(this);
 | 
			
		||||
 | 
			
		||||
  this.collectionName = collectionName;
 | 
			
		||||
  this.numberToReturn = numberToReturn;
 | 
			
		||||
  this.cursorId = cursorId;
 | 
			
		||||
  this.db = db;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inherits(GetMoreCommand, BaseCommand);
 | 
			
		||||
 | 
			
		||||
GetMoreCommand.OP_GET_MORE = 2005;
 | 
			
		||||
 | 
			
		||||
GetMoreCommand.prototype.toBinary = function() {
 | 
			
		||||
  // Validate that we are not passing 0x00 in the colletion name
 | 
			
		||||
  if(!!~this.collectionName.indexOf("\x00")) {
 | 
			
		||||
    throw new Error("namespace cannot contain a null character");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Calculate total length of the document
 | 
			
		||||
  var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + 8 + (4 * 4);
 | 
			
		||||
  // Let's build the single pass buffer command
 | 
			
		||||
  var _index = 0;
 | 
			
		||||
  var _command = new Buffer(totalLengthOfCommand);
 | 
			
		||||
  // Write the header information to the buffer
 | 
			
		||||
  _command[_index++] = totalLengthOfCommand & 0xff;
 | 
			
		||||
  _command[_index++] = (totalLengthOfCommand >> 8) & 0xff;
 | 
			
		||||
  _command[_index++] = (totalLengthOfCommand >> 16) & 0xff;
 | 
			
		||||
  _command[_index++] = (totalLengthOfCommand >> 24) & 0xff;     
 | 
			
		||||
 | 
			
		||||
  // Write the request ID
 | 
			
		||||
  _command[_index++] = this.requestId & 0xff;
 | 
			
		||||
  _command[_index++] = (this.requestId >> 8) & 0xff;
 | 
			
		||||
  _command[_index++] = (this.requestId >> 16) & 0xff;
 | 
			
		||||
  _command[_index++] = (this.requestId >> 24) & 0xff;     
 | 
			
		||||
 | 
			
		||||
  // Write zero
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
 | 
			
		||||
  // Write the op_code for the command
 | 
			
		||||
  _command[_index++] = GetMoreCommand.OP_GET_MORE & 0xff;
 | 
			
		||||
  _command[_index++] = (GetMoreCommand.OP_GET_MORE >> 8) & 0xff;
 | 
			
		||||
  _command[_index++] = (GetMoreCommand.OP_GET_MORE >> 16) & 0xff;
 | 
			
		||||
  _command[_index++] = (GetMoreCommand.OP_GET_MORE >> 24) & 0xff;     
 | 
			
		||||
 | 
			
		||||
  // Write zero
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
 | 
			
		||||
  // Write the collection name to the command
 | 
			
		||||
  _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1;
 | 
			
		||||
  _command[_index - 1] = 0;    
 | 
			
		||||
 | 
			
		||||
  // Number of documents to return
 | 
			
		||||
  _command[_index++] = this.numberToReturn & 0xff;
 | 
			
		||||
  _command[_index++] = (this.numberToReturn >> 8) & 0xff;
 | 
			
		||||
  _command[_index++] = (this.numberToReturn >> 16) & 0xff;
 | 
			
		||||
  _command[_index++] = (this.numberToReturn >> 24) & 0xff;     
 | 
			
		||||
  
 | 
			
		||||
  // Encode the cursor id
 | 
			
		||||
  var low_bits = this.cursorId.getLowBits();
 | 
			
		||||
  // Encode low bits
 | 
			
		||||
  _command[_index++] = low_bits & 0xff;
 | 
			
		||||
  _command[_index++] = (low_bits >> 8) & 0xff;
 | 
			
		||||
  _command[_index++] = (low_bits >> 16) & 0xff;
 | 
			
		||||
  _command[_index++] = (low_bits >> 24) & 0xff;     
 | 
			
		||||
  
 | 
			
		||||
  var high_bits = this.cursorId.getHighBits();
 | 
			
		||||
  // Encode high bits
 | 
			
		||||
  _command[_index++] = high_bits & 0xff;
 | 
			
		||||
  _command[_index++] = (high_bits >> 8) & 0xff;
 | 
			
		||||
  _command[_index++] = (high_bits >> 16) & 0xff;
 | 
			
		||||
  _command[_index++] = (high_bits >> 24) & 0xff;     
 | 
			
		||||
  // Return command
 | 
			
		||||
  return _command;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										161
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/commands/insert_command.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										161
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/commands/insert_command.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,161 @@
 | 
			
		||||
var BaseCommand = require('./base_command').BaseCommand,
 | 
			
		||||
  inherits = require('util').inherits;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Insert Document Command
 | 
			
		||||
**/
 | 
			
		||||
var InsertCommand = exports.InsertCommand = function(db, collectionName, checkKeys, options) {
 | 
			
		||||
  BaseCommand.call(this);
 | 
			
		||||
 | 
			
		||||
  this.collectionName = collectionName;
 | 
			
		||||
  this.documents = [];
 | 
			
		||||
  this.checkKeys = checkKeys == null ? true : checkKeys;
 | 
			
		||||
  this.db = db;
 | 
			
		||||
  this.flags = 0;
 | 
			
		||||
  this.serializeFunctions = false;
 | 
			
		||||
 | 
			
		||||
  // Ensure valid options hash
 | 
			
		||||
  options = options == null ? {} : options;
 | 
			
		||||
 | 
			
		||||
  // Check if we have keepGoing set -> set flag if it's the case
 | 
			
		||||
  if(options['keepGoing'] != null && options['keepGoing']) {
 | 
			
		||||
    // This will finish inserting all non-index violating documents even if it returns an error
 | 
			
		||||
    this.flags = 1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Check if we have keepGoing set -> set flag if it's the case
 | 
			
		||||
  if(options['continueOnError'] != null && options['continueOnError']) {
 | 
			
		||||
    // This will finish inserting all non-index violating documents even if it returns an error
 | 
			
		||||
    this.flags = 1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Let us defined on a command basis if we want functions to be serialized or not
 | 
			
		||||
  if(options['serializeFunctions'] != null && options['serializeFunctions']) {
 | 
			
		||||
    this.serializeFunctions = true;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inherits(InsertCommand, BaseCommand);
 | 
			
		||||
 | 
			
		||||
// OpCodes
 | 
			
		||||
InsertCommand.OP_INSERT =	2002;
 | 
			
		||||
 | 
			
		||||
InsertCommand.prototype.add = function(document) {
 | 
			
		||||
  if(Buffer.isBuffer(document)) {
 | 
			
		||||
    var object_size = document[0] | document[1] << 8 | document[2] << 16 | document[3] << 24;
 | 
			
		||||
    if(object_size != document.length)  {
 | 
			
		||||
      var error = new Error("insert raw message size does not match message header size [" + document.length + "] != [" + object_size + "]");
 | 
			
		||||
      error.name = 'MongoError';
 | 
			
		||||
      throw error;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.documents.push(document);
 | 
			
		||||
  return this;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
struct {
 | 
			
		||||
    MsgHeader header;             // standard message header
 | 
			
		||||
    int32     ZERO;               // 0 - reserved for future use
 | 
			
		||||
    cstring   fullCollectionName; // "dbname.collectionname"
 | 
			
		||||
    BSON[]    documents;          // one or more documents to insert into the collection
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
InsertCommand.prototype.toBinary = function(bsonSettings) {
 | 
			
		||||
  // Validate that we are not passing 0x00 in the colletion name
 | 
			
		||||
  if(!!~this.collectionName.indexOf("\x00")) {
 | 
			
		||||
    throw new Error("namespace cannot contain a null character");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Calculate total length of the document
 | 
			
		||||
  var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + (4 * 4);
 | 
			
		||||
  // var docLength = 0
 | 
			
		||||
  for(var i = 0; i < this.documents.length; i++) {
 | 
			
		||||
    if(Buffer.isBuffer(this.documents[i])) {
 | 
			
		||||
      totalLengthOfCommand += this.documents[i].length;
 | 
			
		||||
    } else {
 | 
			
		||||
      // Calculate size of document
 | 
			
		||||
      totalLengthOfCommand += this.db.bson.calculateObjectSize(this.documents[i], this.serializeFunctions, true);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Enforce maximum bson size
 | 
			
		||||
  if(!bsonSettings.disableDriverBSONSizeCheck 
 | 
			
		||||
    && totalLengthOfCommand > bsonSettings.maxBsonSize) 
 | 
			
		||||
    throw new Error("Document exceeds maximum allowed bson size of " + bsonSettings.maxBsonSize + " bytes");
 | 
			
		||||
 | 
			
		||||
  if(bsonSettings.disableDriverBSONSizeCheck 
 | 
			
		||||
    && totalLengthOfCommand > bsonSettings.maxMessageSizeBytes) 
 | 
			
		||||
    throw new Error("Command exceeds maximum message size of " + bsonSettings.maxMessageSizeBytes + " bytes");
 | 
			
		||||
 | 
			
		||||
  // Let's build the single pass buffer command
 | 
			
		||||
  var _index = 0;
 | 
			
		||||
  var _command = new Buffer(totalLengthOfCommand);
 | 
			
		||||
  // Write the header information to the buffer
 | 
			
		||||
  _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff;
 | 
			
		||||
  _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff;
 | 
			
		||||
  _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff;
 | 
			
		||||
  _command[_index] = totalLengthOfCommand & 0xff;
 | 
			
		||||
  // Adjust index
 | 
			
		||||
  _index = _index + 4;
 | 
			
		||||
  // Write the request ID
 | 
			
		||||
  _command[_index + 3] = (this.requestId >> 24) & 0xff;
 | 
			
		||||
  _command[_index + 2] = (this.requestId >> 16) & 0xff;
 | 
			
		||||
  _command[_index + 1] = (this.requestId >> 8) & 0xff;
 | 
			
		||||
  _command[_index] = this.requestId & 0xff;
 | 
			
		||||
  // Adjust index
 | 
			
		||||
  _index = _index + 4;
 | 
			
		||||
  // Write zero
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  // Write the op_code for the command
 | 
			
		||||
  _command[_index + 3] = (InsertCommand.OP_INSERT >> 24) & 0xff;
 | 
			
		||||
  _command[_index + 2] = (InsertCommand.OP_INSERT >> 16) & 0xff;
 | 
			
		||||
  _command[_index + 1] = (InsertCommand.OP_INSERT >> 8) & 0xff;
 | 
			
		||||
  _command[_index] = InsertCommand.OP_INSERT & 0xff;
 | 
			
		||||
  // Adjust index
 | 
			
		||||
  _index = _index + 4;
 | 
			
		||||
  // Write flags if any
 | 
			
		||||
  _command[_index + 3] = (this.flags >> 24) & 0xff;
 | 
			
		||||
  _command[_index + 2] = (this.flags >> 16) & 0xff;
 | 
			
		||||
  _command[_index + 1] = (this.flags >> 8) & 0xff;
 | 
			
		||||
  _command[_index] = this.flags & 0xff;
 | 
			
		||||
  // Adjust index
 | 
			
		||||
  _index = _index + 4;
 | 
			
		||||
  // Write the collection name to the command
 | 
			
		||||
  _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1;
 | 
			
		||||
  _command[_index - 1] = 0;
 | 
			
		||||
 | 
			
		||||
  // Write all the bson documents to the buffer at the index offset
 | 
			
		||||
  for(var i = 0; i < this.documents.length; i++) {
 | 
			
		||||
    // Document binary length
 | 
			
		||||
    var documentLength = 0
 | 
			
		||||
    var object = this.documents[i];
 | 
			
		||||
 | 
			
		||||
    // Serialize the selector
 | 
			
		||||
    // If we are passing a raw buffer, do minimal validation
 | 
			
		||||
    if(Buffer.isBuffer(object)) {
 | 
			
		||||
      documentLength = object.length;
 | 
			
		||||
      // Copy the data into the current buffer
 | 
			
		||||
      object.copy(_command, _index);
 | 
			
		||||
    } else {
 | 
			
		||||
      // Serialize the document straight to the buffer
 | 
			
		||||
      documentLength = this.db.bson.serializeWithBufferAndIndex(object, this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Write the length to the document
 | 
			
		||||
    _command[_index + 3] = (documentLength >> 24) & 0xff;
 | 
			
		||||
    _command[_index + 2] = (documentLength >> 16) & 0xff;
 | 
			
		||||
    _command[_index + 1] = (documentLength >> 8) & 0xff;
 | 
			
		||||
    _command[_index] = documentLength & 0xff;
 | 
			
		||||
    // Update index in buffer
 | 
			
		||||
    _index = _index + documentLength;
 | 
			
		||||
    // Add terminating 0 for the object
 | 
			
		||||
    _command[_index - 1] = 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return _command;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										98
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/commands/kill_cursor_command.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										98
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/commands/kill_cursor_command.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,98 @@
 | 
			
		||||
var BaseCommand = require('./base_command').BaseCommand,
 | 
			
		||||
  inherits = require('util').inherits,
 | 
			
		||||
  binaryutils = require('../utils');
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Insert Document Command
 | 
			
		||||
**/
 | 
			
		||||
var KillCursorCommand = exports.KillCursorCommand = function(db, cursorIds) {
 | 
			
		||||
  BaseCommand.call(this);
 | 
			
		||||
 | 
			
		||||
  this.cursorIds = cursorIds;
 | 
			
		||||
  this.db = db;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inherits(KillCursorCommand, BaseCommand);
 | 
			
		||||
 | 
			
		||||
KillCursorCommand.OP_KILL_CURSORS = 2007;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
struct {
 | 
			
		||||
    MsgHeader header;                 // standard message header
 | 
			
		||||
    int32     ZERO;                   // 0 - reserved for future use
 | 
			
		||||
    int32     numberOfCursorIDs;      // number of cursorIDs in message
 | 
			
		||||
    int64[]   cursorIDs;                // array of cursorIDs to close
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
KillCursorCommand.prototype.toBinary = function() {
 | 
			
		||||
  // Calculate total length of the document
 | 
			
		||||
  var totalLengthOfCommand = 4 + 4 + (4 * 4) + (this.cursorIds.length * 8);
 | 
			
		||||
  // Let's build the single pass buffer command
 | 
			
		||||
  var _index = 0;
 | 
			
		||||
  var _command = new Buffer(totalLengthOfCommand);
 | 
			
		||||
  // Write the header information to the buffer
 | 
			
		||||
  _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff;     
 | 
			
		||||
  _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff;
 | 
			
		||||
  _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff;
 | 
			
		||||
  _command[_index] = totalLengthOfCommand & 0xff;
 | 
			
		||||
  // Adjust index
 | 
			
		||||
  _index = _index + 4;
 | 
			
		||||
  // Write the request ID
 | 
			
		||||
  _command[_index + 3] = (this.requestId >> 24) & 0xff;     
 | 
			
		||||
  _command[_index + 2] = (this.requestId >> 16) & 0xff;
 | 
			
		||||
  _command[_index + 1] = (this.requestId >> 8) & 0xff;
 | 
			
		||||
  _command[_index] = this.requestId & 0xff;
 | 
			
		||||
  // Adjust index
 | 
			
		||||
  _index = _index + 4;
 | 
			
		||||
  // Write zero
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  // Write the op_code for the command
 | 
			
		||||
  _command[_index + 3] = (KillCursorCommand.OP_KILL_CURSORS >> 24) & 0xff;     
 | 
			
		||||
  _command[_index + 2] = (KillCursorCommand.OP_KILL_CURSORS >> 16) & 0xff;
 | 
			
		||||
  _command[_index + 1] = (KillCursorCommand.OP_KILL_CURSORS >> 8) & 0xff;
 | 
			
		||||
  _command[_index] = KillCursorCommand.OP_KILL_CURSORS & 0xff;
 | 
			
		||||
  // Adjust index
 | 
			
		||||
  _index = _index + 4;
 | 
			
		||||
 | 
			
		||||
  // Write zero
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
 | 
			
		||||
  // Number of cursors to kill
 | 
			
		||||
  var numberOfCursors = this.cursorIds.length;
 | 
			
		||||
  _command[_index + 3] = (numberOfCursors >> 24) & 0xff;     
 | 
			
		||||
  _command[_index + 2] = (numberOfCursors >> 16) & 0xff;
 | 
			
		||||
  _command[_index + 1] = (numberOfCursors >> 8) & 0xff;
 | 
			
		||||
  _command[_index] = numberOfCursors & 0xff;
 | 
			
		||||
  // Adjust index
 | 
			
		||||
  _index = _index + 4;
 | 
			
		||||
 | 
			
		||||
  // Encode all the cursors
 | 
			
		||||
  for(var i = 0; i < this.cursorIds.length; i++) {
 | 
			
		||||
    // Encode the cursor id
 | 
			
		||||
    var low_bits = this.cursorIds[i].getLowBits();
 | 
			
		||||
    // Encode low bits
 | 
			
		||||
    _command[_index + 3] = (low_bits >> 24) & 0xff;     
 | 
			
		||||
    _command[_index + 2] = (low_bits >> 16) & 0xff;
 | 
			
		||||
    _command[_index + 1] = (low_bits >> 8) & 0xff;
 | 
			
		||||
    _command[_index] = low_bits & 0xff;
 | 
			
		||||
    // Adjust index
 | 
			
		||||
    _index = _index + 4;
 | 
			
		||||
      
 | 
			
		||||
    var high_bits = this.cursorIds[i].getHighBits();
 | 
			
		||||
    // Encode high bits
 | 
			
		||||
    _command[_index + 3] = (high_bits >> 24) & 0xff;     
 | 
			
		||||
    _command[_index + 2] = (high_bits >> 16) & 0xff;
 | 
			
		||||
    _command[_index + 1] = (high_bits >> 8) & 0xff;
 | 
			
		||||
    _command[_index] = high_bits & 0xff;
 | 
			
		||||
    // Adjust index
 | 
			
		||||
    _index = _index + 4;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  return _command;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										296
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/commands/query_command.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										296
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/commands/query_command.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,296 @@
 | 
			
		||||
var BaseCommand = require('./base_command').BaseCommand,
 | 
			
		||||
  inherits = require('util').inherits;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Insert Document Command
 | 
			
		||||
**/
 | 
			
		||||
var QueryCommand = exports.QueryCommand = function(db, collectionName, queryOptions, numberToSkip, numberToReturn, query, returnFieldSelector, options) {
 | 
			
		||||
  BaseCommand.call(this);
 | 
			
		||||
 | 
			
		||||
  // Validate correctness off the selector
 | 
			
		||||
  var object = query,
 | 
			
		||||
    object_size;
 | 
			
		||||
  if(Buffer.isBuffer(object)) {
 | 
			
		||||
    object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24;
 | 
			
		||||
    if(object_size != object.length) {
 | 
			
		||||
      var error = new Error("query selector raw message size does not match message header size [" + object.length + "] != [" + object_size + "]");
 | 
			
		||||
      error.name = 'MongoError';
 | 
			
		||||
      throw error;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  object = returnFieldSelector;
 | 
			
		||||
  if(Buffer.isBuffer(object)) {
 | 
			
		||||
    object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24;
 | 
			
		||||
    if(object_size != object.length) {
 | 
			
		||||
      var error = new Error("query fields raw message size does not match message header size [" + object.length + "] != [" + object_size + "]");
 | 
			
		||||
      error.name = 'MongoError';
 | 
			
		||||
      throw error;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Make sure we don't get a null exception
 | 
			
		||||
  options = options == null ? {} : options;
 | 
			
		||||
  // Set up options
 | 
			
		||||
  this.collectionName = collectionName;
 | 
			
		||||
  this.queryOptions = queryOptions;
 | 
			
		||||
  this.numberToSkip = numberToSkip;
 | 
			
		||||
  this.numberToReturn = numberToReturn;
 | 
			
		||||
 | 
			
		||||
  // Ensure we have no null query
 | 
			
		||||
  query = query == null ? {} : query;
 | 
			
		||||
  // Wrap query in the $query parameter so we can add read preferences for mongos
 | 
			
		||||
  this.query = query;
 | 
			
		||||
  this.returnFieldSelector = returnFieldSelector;
 | 
			
		||||
  this.db = db;
 | 
			
		||||
 | 
			
		||||
  // Force the slave ok flag to be set if we are not using primary read preference
 | 
			
		||||
  if(this.db && this.db.slaveOk) {
 | 
			
		||||
    this.queryOptions |= QueryCommand.OPTS_SLAVE;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // If checkKeys set
 | 
			
		||||
  this.checkKeys = typeof options.checkKeys == 'boolean' ? options.checkKeys : false;
 | 
			
		||||
 | 
			
		||||
  // Let us defined on a command basis if we want functions to be serialized or not
 | 
			
		||||
  if(options['serializeFunctions'] != null && options['serializeFunctions']) {
 | 
			
		||||
    this.serializeFunctions = true;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inherits(QueryCommand, BaseCommand);
 | 
			
		||||
 | 
			
		||||
QueryCommand.OP_QUERY = 2004;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Adds the read prefrence to the current command
 | 
			
		||||
 */
 | 
			
		||||
QueryCommand.prototype.setMongosReadPreference = function(readPreference, tags) {
 | 
			
		||||
  // No read preference specified
 | 
			
		||||
  if(readPreference == false) return;
 | 
			
		||||
  // If we have readPreference set to true set to secondary prefered
 | 
			
		||||
  if(readPreference == true) {
 | 
			
		||||
    readPreference = 'secondaryPreferred';
 | 
			
		||||
  } else if(readPreference == 'false') {
 | 
			
		||||
    readPreference = 'primary';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // If we have primary read preference ignore it
 | 
			
		||||
  if(readPreference == 'primary' 
 | 
			
		||||
    || readPreference.mode == 'primary') return;
 | 
			
		||||
 | 
			
		||||
  // Force the slave ok flag to be set if we are not using primary read preference
 | 
			
		||||
  if(readPreference != false && readPreference != 'primary') {
 | 
			
		||||
    this.queryOptions |= QueryCommand.OPTS_SLAVE;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Backward compatibility, ensure $query only set on read preference so 1.8.X works
 | 
			
		||||
  if((readPreference != null || tags != null) && this.query['$query'] == null) {
 | 
			
		||||
    this.query = {'$query': this.query};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // If we have no readPreference set and no tags, check if the slaveOk bit is set
 | 
			
		||||
  if(readPreference == null && tags == null) {
 | 
			
		||||
    // If we have a slaveOk bit set the read preference for MongoS
 | 
			
		||||
    if(this.queryOptions & QueryCommand.OPTS_SLAVE) {
 | 
			
		||||
      this.query['$readPreference'] = {mode: 'secondary'}
 | 
			
		||||
    } else {
 | 
			
		||||
      this.query['$readPreference'] = {mode: 'primary'}
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Build read preference object
 | 
			
		||||
  if(typeof readPreference == 'object' && readPreference['_type'] == 'ReadPreference') {
 | 
			
		||||
    this.query['$readPreference'] = readPreference.toObject();
 | 
			
		||||
  } else if(readPreference != null) {
 | 
			
		||||
    // Add the read preference
 | 
			
		||||
    this.query['$readPreference'] = {mode: readPreference};
 | 
			
		||||
 | 
			
		||||
    // If we have tags let's add them
 | 
			
		||||
    if(tags != null) {
 | 
			
		||||
      this.query['$readPreference']['tags'] = tags;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
struct {
 | 
			
		||||
    MsgHeader header;                 // standard message header
 | 
			
		||||
    int32     opts;                   // query options.  See below for details.
 | 
			
		||||
    cstring   fullCollectionName;     // "dbname.collectionname"
 | 
			
		||||
    int32     numberToSkip;           // number of documents to skip when returning results
 | 
			
		||||
    int32     numberToReturn;         // number of documents to return in the first OP_REPLY
 | 
			
		||||
    BSON      query ;                 // query object.  See below for details.
 | 
			
		||||
  [ BSON      returnFieldSelector; ]  // OPTIONAL : selector indicating the fields to return.  See below for details.
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
QueryCommand.prototype.toBinary = function(bsonSettings) {
 | 
			
		||||
  // Validate that we are not passing 0x00 in the colletion name
 | 
			
		||||
  if(!!~this.collectionName.indexOf("\x00")) {
 | 
			
		||||
    throw new Error("namespace cannot contain a null character");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Total length of the command
 | 
			
		||||
  var totalLengthOfCommand = 0;
 | 
			
		||||
  // Calculate total length of the document
 | 
			
		||||
  if(Buffer.isBuffer(this.query)) {
 | 
			
		||||
    totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + 4 + this.query.length + (4 * 4);
 | 
			
		||||
  } else {
 | 
			
		||||
    totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + 4 + this.db.bson.calculateObjectSize(this.query, this.serializeFunctions, true) + (4 * 4);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Calculate extra fields size
 | 
			
		||||
  if(this.returnFieldSelector != null && !(Buffer.isBuffer(this.returnFieldSelector)))  {
 | 
			
		||||
    if(Object.keys(this.returnFieldSelector).length > 0) {
 | 
			
		||||
      totalLengthOfCommand += this.db.bson.calculateObjectSize(this.returnFieldSelector, this.serializeFunctions, true);
 | 
			
		||||
    }
 | 
			
		||||
  } else if(Buffer.isBuffer(this.returnFieldSelector)) {
 | 
			
		||||
    totalLengthOfCommand += this.returnFieldSelector.length;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Enforce maximum bson size
 | 
			
		||||
  if(!bsonSettings.disableDriverBSONSizeCheck 
 | 
			
		||||
    && totalLengthOfCommand > bsonSettings.maxBsonSize) 
 | 
			
		||||
    throw new Error("Document exceeds maximum allowed bson size of " + bsonSettings.maxBsonSize + " bytes");
 | 
			
		||||
 | 
			
		||||
  if(bsonSettings.disableDriverBSONSizeCheck 
 | 
			
		||||
    && totalLengthOfCommand > bsonSettings.maxMessageSizeBytes) 
 | 
			
		||||
    throw new Error("Command exceeds maximum message size of " + bsonSettings.maxMessageSizeBytes + " bytes");
 | 
			
		||||
 | 
			
		||||
  // Let's build the single pass buffer command
 | 
			
		||||
  var _index = 0;
 | 
			
		||||
  var _command = new Buffer(totalLengthOfCommand);
 | 
			
		||||
  // Write the header information to the buffer
 | 
			
		||||
  _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff;
 | 
			
		||||
  _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff;
 | 
			
		||||
  _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff;
 | 
			
		||||
  _command[_index] = totalLengthOfCommand & 0xff;
 | 
			
		||||
  // Adjust index
 | 
			
		||||
  _index = _index + 4;
 | 
			
		||||
  // Write the request ID
 | 
			
		||||
  _command[_index + 3] = (this.requestId >> 24) & 0xff;
 | 
			
		||||
  _command[_index + 2] = (this.requestId >> 16) & 0xff;
 | 
			
		||||
  _command[_index + 1] = (this.requestId >> 8) & 0xff;
 | 
			
		||||
  _command[_index] = this.requestId & 0xff;
 | 
			
		||||
  // Adjust index
 | 
			
		||||
  _index = _index + 4;
 | 
			
		||||
  // Write zero
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  // Write the op_code for the command
 | 
			
		||||
  _command[_index + 3] = (QueryCommand.OP_QUERY >> 24) & 0xff;
 | 
			
		||||
  _command[_index + 2] = (QueryCommand.OP_QUERY >> 16) & 0xff;
 | 
			
		||||
  _command[_index + 1] = (QueryCommand.OP_QUERY >> 8) & 0xff;
 | 
			
		||||
  _command[_index] = QueryCommand.OP_QUERY & 0xff;
 | 
			
		||||
  // Adjust index
 | 
			
		||||
  _index = _index + 4;
 | 
			
		||||
 | 
			
		||||
  // Write the query options
 | 
			
		||||
  _command[_index + 3] = (this.queryOptions >> 24) & 0xff;
 | 
			
		||||
  _command[_index + 2] = (this.queryOptions >> 16) & 0xff;
 | 
			
		||||
  _command[_index + 1] = (this.queryOptions >> 8) & 0xff;
 | 
			
		||||
  _command[_index] = this.queryOptions & 0xff;
 | 
			
		||||
  // Adjust index
 | 
			
		||||
  _index = _index + 4;
 | 
			
		||||
 | 
			
		||||
  // Write the collection name to the command
 | 
			
		||||
  _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1;
 | 
			
		||||
  _command[_index - 1] = 0;
 | 
			
		||||
 | 
			
		||||
  // Write the number of documents to skip
 | 
			
		||||
  _command[_index + 3] = (this.numberToSkip >> 24) & 0xff;
 | 
			
		||||
  _command[_index + 2] = (this.numberToSkip >> 16) & 0xff;
 | 
			
		||||
  _command[_index + 1] = (this.numberToSkip >> 8) & 0xff;
 | 
			
		||||
  _command[_index] = this.numberToSkip & 0xff;
 | 
			
		||||
  // Adjust index
 | 
			
		||||
  _index = _index + 4;
 | 
			
		||||
 | 
			
		||||
  // Write the number of documents to return
 | 
			
		||||
  _command[_index + 3] = (this.numberToReturn >> 24) & 0xff;
 | 
			
		||||
  _command[_index + 2] = (this.numberToReturn >> 16) & 0xff;
 | 
			
		||||
  _command[_index + 1] = (this.numberToReturn >> 8) & 0xff;
 | 
			
		||||
  _command[_index] = this.numberToReturn & 0xff;
 | 
			
		||||
  // Adjust index
 | 
			
		||||
  _index = _index + 4;
 | 
			
		||||
 | 
			
		||||
  // Document binary length
 | 
			
		||||
  var documentLength = 0
 | 
			
		||||
  var object = this.query;
 | 
			
		||||
 | 
			
		||||
  // Serialize the selector
 | 
			
		||||
  if(Buffer.isBuffer(object)) {
 | 
			
		||||
    documentLength = object.length;
 | 
			
		||||
    // Copy the data into the current buffer
 | 
			
		||||
    object.copy(_command, _index);
 | 
			
		||||
  } else {
 | 
			
		||||
    // If $query we need to check for a valid document
 | 
			
		||||
    if(this.query['$query']) {
 | 
			
		||||
      this.db.bson.serializeWithBufferAndIndex(object['$query'], this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1;
 | 
			
		||||
      // Cannot check keys due to $query
 | 
			
		||||
      this.checkKeys = false;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Serialize the document straight to the buffer
 | 
			
		||||
    documentLength = this.db.bson.serializeWithBufferAndIndex(object, this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Write the length to the document
 | 
			
		||||
  _command[_index + 3] = (documentLength >> 24) & 0xff;
 | 
			
		||||
  _command[_index + 2] = (documentLength >> 16) & 0xff;
 | 
			
		||||
  _command[_index + 1] = (documentLength >> 8) & 0xff;
 | 
			
		||||
  _command[_index] = documentLength & 0xff;
 | 
			
		||||
  // Update index in buffer
 | 
			
		||||
  _index = _index + documentLength;
 | 
			
		||||
  // // Add terminating 0 for the object
 | 
			
		||||
  _command[_index - 1] = 0;
 | 
			
		||||
 | 
			
		||||
  // Push field selector if available
 | 
			
		||||
  if(this.returnFieldSelector != null && !(Buffer.isBuffer(this.returnFieldSelector)))  {
 | 
			
		||||
    if(Object.keys(this.returnFieldSelector).length > 0) {
 | 
			
		||||
      var documentLength = this.db.bson.serializeWithBufferAndIndex(this.returnFieldSelector, this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1;
 | 
			
		||||
      // Write the length to the document
 | 
			
		||||
      _command[_index + 3] = (documentLength >> 24) & 0xff;
 | 
			
		||||
      _command[_index + 2] = (documentLength >> 16) & 0xff;
 | 
			
		||||
      _command[_index + 1] = (documentLength >> 8) & 0xff;
 | 
			
		||||
      _command[_index] = documentLength & 0xff;
 | 
			
		||||
      // Update index in buffer
 | 
			
		||||
      _index = _index + documentLength;
 | 
			
		||||
      // Add terminating 0 for the object
 | 
			
		||||
      _command[_index - 1] = 0;
 | 
			
		||||
    }
 | 
			
		||||
  } if(this.returnFieldSelector != null && Buffer.isBuffer(this.returnFieldSelector))  {
 | 
			
		||||
    // Document binary length
 | 
			
		||||
    var documentLength = 0
 | 
			
		||||
    var object = this.returnFieldSelector;
 | 
			
		||||
 | 
			
		||||
    // Serialize the selector
 | 
			
		||||
    documentLength = object.length;
 | 
			
		||||
    // Copy the data into the current buffer
 | 
			
		||||
    object.copy(_command, _index);
 | 
			
		||||
 | 
			
		||||
    // Write the length to the document
 | 
			
		||||
    _command[_index + 3] = (documentLength >> 24) & 0xff;
 | 
			
		||||
    _command[_index + 2] = (documentLength >> 16) & 0xff;
 | 
			
		||||
    _command[_index + 1] = (documentLength >> 8) & 0xff;
 | 
			
		||||
    _command[_index] = documentLength & 0xff;
 | 
			
		||||
    // Update index in buffer
 | 
			
		||||
    _index = _index + documentLength;
 | 
			
		||||
    // Add terminating 0 for the object
 | 
			
		||||
    _command[_index - 1] = 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Return finished command
 | 
			
		||||
  return _command;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Constants
 | 
			
		||||
QueryCommand.OPTS_NONE = 0;
 | 
			
		||||
QueryCommand.OPTS_TAILABLE_CURSOR = 2;
 | 
			
		||||
QueryCommand.OPTS_SLAVE = 4;
 | 
			
		||||
QueryCommand.OPTS_OPLOG_REPLAY = 8;
 | 
			
		||||
QueryCommand.OPTS_NO_CURSOR_TIMEOUT = 16;
 | 
			
		||||
QueryCommand.OPTS_AWAIT_DATA = 32;
 | 
			
		||||
QueryCommand.OPTS_EXHAUST = 64;
 | 
			
		||||
QueryCommand.OPTS_PARTIAL = 128;
 | 
			
		||||
							
								
								
									
										189
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/commands/update_command.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										189
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/commands/update_command.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,189 @@
 | 
			
		||||
var BaseCommand = require('./base_command').BaseCommand,
 | 
			
		||||
  inherits = require('util').inherits;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Update Document Command
 | 
			
		||||
**/
 | 
			
		||||
var UpdateCommand = exports.UpdateCommand = function(db, collectionName, spec, document, options) {
 | 
			
		||||
  BaseCommand.call(this);
 | 
			
		||||
 | 
			
		||||
  var object = spec;
 | 
			
		||||
  if(Buffer.isBuffer(object)) {
 | 
			
		||||
    var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24;    
 | 
			
		||||
    if(object_size != object.length)  {
 | 
			
		||||
      var error = new Error("update spec raw message size does not match message header size [" + object.length + "] != [" + object_size + "]");
 | 
			
		||||
      error.name = 'MongoError';
 | 
			
		||||
      throw error;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var object = document;
 | 
			
		||||
  if(Buffer.isBuffer(object)) {
 | 
			
		||||
    var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24;    
 | 
			
		||||
    if(object_size != object.length)  {
 | 
			
		||||
      var error = new Error("update document raw message size does not match message header size [" + object.length + "] != [" + object_size + "]");
 | 
			
		||||
      error.name = 'MongoError';
 | 
			
		||||
      throw error;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.collectionName = collectionName;
 | 
			
		||||
  this.spec = spec;
 | 
			
		||||
  this.document = document;
 | 
			
		||||
  this.db = db;
 | 
			
		||||
  this.serializeFunctions = false;
 | 
			
		||||
  this.checkKeys = typeof options.checkKeys != 'boolean' ? false : options.checkKeys;
 | 
			
		||||
 | 
			
		||||
  // Generate correct flags
 | 
			
		||||
  var db_upsert = 0;
 | 
			
		||||
  var db_multi_update = 0;
 | 
			
		||||
  db_upsert = options != null && options['upsert'] != null ? (options['upsert'] == true ? 1 : 0) : db_upsert;
 | 
			
		||||
  db_multi_update = options != null && options['multi'] != null ? (options['multi'] == true ? 1 : 0) : db_multi_update;
 | 
			
		||||
 | 
			
		||||
  // Flags
 | 
			
		||||
  this.flags = parseInt(db_multi_update.toString() + db_upsert.toString(), 2);
 | 
			
		||||
  // Let us defined on a command basis if we want functions to be serialized or not
 | 
			
		||||
  if(options['serializeFunctions'] != null && options['serializeFunctions']) {
 | 
			
		||||
    this.serializeFunctions = true;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inherits(UpdateCommand, BaseCommand);
 | 
			
		||||
 | 
			
		||||
UpdateCommand.OP_UPDATE = 2001;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
struct {
 | 
			
		||||
    MsgHeader header;             // standard message header
 | 
			
		||||
    int32     ZERO;               // 0 - reserved for future use
 | 
			
		||||
    cstring   fullCollectionName; // "dbname.collectionname"
 | 
			
		||||
    int32     flags;              // bit vector. see below
 | 
			
		||||
    BSON      spec;               // the query to select the document
 | 
			
		||||
    BSON      document;           // the document data to update with or insert
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
UpdateCommand.prototype.toBinary = function(bsonSettings) {
 | 
			
		||||
  // Validate that we are not passing 0x00 in the colletion name
 | 
			
		||||
  if(!!~this.collectionName.indexOf("\x00")) {
 | 
			
		||||
    throw new Error("namespace cannot contain a null character");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Calculate total length of the document
 | 
			
		||||
  var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + this.db.bson.calculateObjectSize(this.spec, false, true) +
 | 
			
		||||
      this.db.bson.calculateObjectSize(this.document, this.serializeFunctions, true) + (4 * 4);
 | 
			
		||||
 | 
			
		||||
  // Enforce maximum bson size
 | 
			
		||||
  if(!bsonSettings.disableDriverBSONSizeCheck 
 | 
			
		||||
    && totalLengthOfCommand > bsonSettings.maxBsonSize) 
 | 
			
		||||
    throw new Error("Document exceeds maximum allowed bson size of " + bsonSettings.maxBsonSize + " bytes");
 | 
			
		||||
 | 
			
		||||
  if(bsonSettings.disableDriverBSONSizeCheck 
 | 
			
		||||
    && totalLengthOfCommand > bsonSettings.maxMessageSizeBytes) 
 | 
			
		||||
    throw new Error("Command exceeds maximum message size of " + bsonSettings.maxMessageSizeBytes + " bytes");
 | 
			
		||||
 | 
			
		||||
  // Let's build the single pass buffer command
 | 
			
		||||
  var _index = 0;
 | 
			
		||||
  var _command = new Buffer(totalLengthOfCommand);
 | 
			
		||||
  // Write the header information to the buffer
 | 
			
		||||
  _command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff;     
 | 
			
		||||
  _command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff;
 | 
			
		||||
  _command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff;
 | 
			
		||||
  _command[_index] = totalLengthOfCommand & 0xff;
 | 
			
		||||
  // Adjust index
 | 
			
		||||
  _index = _index + 4;
 | 
			
		||||
  // Write the request ID
 | 
			
		||||
  _command[_index + 3] = (this.requestId >> 24) & 0xff;     
 | 
			
		||||
  _command[_index + 2] = (this.requestId >> 16) & 0xff;
 | 
			
		||||
  _command[_index + 1] = (this.requestId >> 8) & 0xff;
 | 
			
		||||
  _command[_index] = this.requestId & 0xff;
 | 
			
		||||
  // Adjust index
 | 
			
		||||
  _index = _index + 4;
 | 
			
		||||
  // Write zero
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  // Write the op_code for the command
 | 
			
		||||
  _command[_index + 3] = (UpdateCommand.OP_UPDATE >> 24) & 0xff;     
 | 
			
		||||
  _command[_index + 2] = (UpdateCommand.OP_UPDATE >> 16) & 0xff;
 | 
			
		||||
  _command[_index + 1] = (UpdateCommand.OP_UPDATE >> 8) & 0xff;
 | 
			
		||||
  _command[_index] = UpdateCommand.OP_UPDATE & 0xff;
 | 
			
		||||
  // Adjust index
 | 
			
		||||
  _index = _index + 4;
 | 
			
		||||
 | 
			
		||||
  // Write zero
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
  _command[_index++] = 0;
 | 
			
		||||
 | 
			
		||||
  // Write the collection name to the command
 | 
			
		||||
  _index = _index + _command.write(this.collectionName, _index, 'utf8') + 1;
 | 
			
		||||
  _command[_index - 1] = 0;    
 | 
			
		||||
 | 
			
		||||
  // Write the update flags
 | 
			
		||||
  _command[_index + 3] = (this.flags >> 24) & 0xff;     
 | 
			
		||||
  _command[_index + 2] = (this.flags >> 16) & 0xff;
 | 
			
		||||
  _command[_index + 1] = (this.flags >> 8) & 0xff;
 | 
			
		||||
  _command[_index] = this.flags & 0xff;
 | 
			
		||||
  // Adjust index
 | 
			
		||||
  _index = _index + 4;
 | 
			
		||||
 | 
			
		||||
  // Document binary length
 | 
			
		||||
  var documentLength = 0
 | 
			
		||||
  var object = this.spec;
 | 
			
		||||
 | 
			
		||||
  // Serialize the selector
 | 
			
		||||
  // If we are passing a raw buffer, do minimal validation
 | 
			
		||||
  if(Buffer.isBuffer(object)) {
 | 
			
		||||
    var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24;
 | 
			
		||||
    if(object_size != object.length) throw new Error("raw message size does not match message header size [" + object.length + "] != [" + object_size + "]");
 | 
			
		||||
    documentLength = object.length;
 | 
			
		||||
    // Copy the data into the current buffer
 | 
			
		||||
    object.copy(_command, _index);
 | 
			
		||||
  } else {
 | 
			
		||||
    documentLength = this.db.bson.serializeWithBufferAndIndex(object, this.checkKeys, _command, _index, false) - _index + 1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Write the length to the document
 | 
			
		||||
  _command[_index + 3] = (documentLength >> 24) & 0xff;     
 | 
			
		||||
  _command[_index + 2] = (documentLength >> 16) & 0xff;
 | 
			
		||||
  _command[_index + 1] = (documentLength >> 8) & 0xff;
 | 
			
		||||
  _command[_index] = documentLength & 0xff;
 | 
			
		||||
  // Update index in buffer
 | 
			
		||||
  _index = _index + documentLength;
 | 
			
		||||
  // Add terminating 0 for the object
 | 
			
		||||
  _command[_index - 1] = 0;    
 | 
			
		||||
 | 
			
		||||
  // Document binary length
 | 
			
		||||
  var documentLength = 0
 | 
			
		||||
  var object = this.document;
 | 
			
		||||
 | 
			
		||||
  // Serialize the document
 | 
			
		||||
  // If we are passing a raw buffer, do minimal validation
 | 
			
		||||
  if(Buffer.isBuffer(object)) {
 | 
			
		||||
    var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24;
 | 
			
		||||
    if(object_size != object.length) throw new Error("raw message size does not match message header size [" + object.length + "] != [" + object_size + "]");
 | 
			
		||||
    documentLength = object.length;
 | 
			
		||||
    // Copy the data into the current buffer
 | 
			
		||||
    object.copy(_command, _index);
 | 
			
		||||
  } else {    
 | 
			
		||||
    documentLength = this.db.bson.serializeWithBufferAndIndex(object, false, _command, _index, this.serializeFunctions) - _index + 1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Write the length to the document
 | 
			
		||||
  _command[_index + 3] = (documentLength >> 24) & 0xff;     
 | 
			
		||||
  _command[_index + 2] = (documentLength >> 16) & 0xff;
 | 
			
		||||
  _command[_index + 1] = (documentLength >> 8) & 0xff;
 | 
			
		||||
  _command[_index] = documentLength & 0xff;
 | 
			
		||||
  // Update index in buffer
 | 
			
		||||
  _index = _index + documentLength;
 | 
			
		||||
  // Add terminating 0 for the object
 | 
			
		||||
  _command[_index - 1] = 0;    
 | 
			
		||||
 | 
			
		||||
  return _command;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Constants
 | 
			
		||||
UpdateCommand.DB_UPSERT = 0;
 | 
			
		||||
UpdateCommand.DB_MULTI_UPDATE = 1;
 | 
			
		||||
							
								
								
									
										515
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/base.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										515
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/base.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,515 @@
 | 
			
		||||
var EventEmitter = require('events').EventEmitter
 | 
			
		||||
  , inherits = require('util').inherits
 | 
			
		||||
  , utils = require('../utils')
 | 
			
		||||
  , mongodb_cr_authenticate = require('../auth/mongodb_cr.js').authenticate
 | 
			
		||||
  , mongodb_gssapi_authenticate = require('../auth/mongodb_gssapi.js').authenticate
 | 
			
		||||
  , mongodb_sspi_authenticate = require('../auth/mongodb_sspi.js').authenticate
 | 
			
		||||
  , mongodb_plain_authenticate = require('../auth/mongodb_plain.js').authenticate
 | 
			
		||||
  , mongodb_x509_authenticate = require('../auth/mongodb_x509.js').authenticate
 | 
			
		||||
  , mongodb_scram_authenticate = require('../auth/mongodb_scram.js').authenticate;
 | 
			
		||||
 | 
			
		||||
var id = 0;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Internal class for callback storage
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
var CallbackStore = function() {
 | 
			
		||||
  // Make class an event emitter
 | 
			
		||||
  EventEmitter.call(this);
 | 
			
		||||
  // Add a info about call variable
 | 
			
		||||
  this._notReplied = {};
 | 
			
		||||
  this.id = id++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
inherits(CallbackStore, EventEmitter);
 | 
			
		||||
 | 
			
		||||
CallbackStore.prototype.notRepliedToIds = function() {
 | 
			
		||||
  return Object.keys(this._notReplied);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CallbackStore.prototype.callbackInfo = function(id) {
 | 
			
		||||
  return this._notReplied[id]; 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Internal class for holding non-executed commands
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
var NonExecutedOperationStore = function(config) {  
 | 
			
		||||
  var commands = {
 | 
			
		||||
      read: []
 | 
			
		||||
    , write_reads: []
 | 
			
		||||
    , write: []
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // Execute all callbacks
 | 
			
		||||
  var fireCallbacksWithError = function(error, commands) {
 | 
			
		||||
    while(commands.length > 0) {
 | 
			
		||||
      var command = commands.shift();
 | 
			
		||||
      if(typeof command.callback == 'function') {
 | 
			
		||||
        command.callback(error);        
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.count = function() {
 | 
			
		||||
    return commands.read.length
 | 
			
		||||
      + commands.write_reads.length
 | 
			
		||||
      + commands.write.length;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.write = function(op) {
 | 
			
		||||
    commands.write.push(op);
 | 
			
		||||
  }  
 | 
			
		||||
 | 
			
		||||
  this.read_from_writer = function(op) {  
 | 
			
		||||
    commands.write_reads.push(op);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.read = function(op) {  
 | 
			
		||||
    commands.read.push(op);
 | 
			
		||||
  }  
 | 
			
		||||
 | 
			
		||||
  this.validateBufferLimit = function(numberToFailOn) {
 | 
			
		||||
    if(numberToFailOn == -1 || numberToFailOn == null) 
 | 
			
		||||
      return true;
 | 
			
		||||
 | 
			
		||||
    // Error passed back
 | 
			
		||||
    var error = utils.toError("No connection operations buffering limit of " + numberToFailOn + " reached");
 | 
			
		||||
 | 
			
		||||
    // If we have passed the number of items to buffer we need to fail
 | 
			
		||||
    if(numberToFailOn < this.count()) {
 | 
			
		||||
      // Fail all of the callbacks
 | 
			
		||||
      fireCallbacksWithError(error, commands.read);
 | 
			
		||||
      fireCallbacksWithError(error, commands.write_reads);
 | 
			
		||||
      fireCallbacksWithError(error, commands.write);
 | 
			
		||||
 | 
			
		||||
      // Report back that the buffer has been filled
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // There is still some room to go
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.execute_queries = function(executeInsertCommand) {
 | 
			
		||||
    var connection = config.checkoutReader();
 | 
			
		||||
    if(connection == null || connection instanceof Error) return;
 | 
			
		||||
 | 
			
		||||
    // Write out all the queries
 | 
			
		||||
    while(commands.read.length > 0) {
 | 
			
		||||
      // Get the next command
 | 
			
		||||
      var command = commands.read.shift();
 | 
			
		||||
      command.options.connection = connection;
 | 
			
		||||
      // Execute the next command
 | 
			
		||||
      command.executeQueryCommand(command.db, command.db_command, command.options, command.callback);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.execute_writes = function() {
 | 
			
		||||
    var connection = config.checkoutWriter();
 | 
			
		||||
    if(connection == null || connection instanceof Error) return;
 | 
			
		||||
 | 
			
		||||
    // Write out all the queries to the primary
 | 
			
		||||
    while(commands.write_reads.length > 0) {
 | 
			
		||||
      // Get the next command
 | 
			
		||||
      var command = commands.write_reads.shift();
 | 
			
		||||
      command.options.connection = connection;
 | 
			
		||||
      // Execute the next command
 | 
			
		||||
      command.executeQueryCommand(command.db, command.db_command, command.options, command.callback);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Execute all write operations
 | 
			
		||||
    while(commands.write.length > 0) {
 | 
			
		||||
      // Get the next command
 | 
			
		||||
      var command = commands.write.shift();
 | 
			
		||||
      // Set the connection
 | 
			
		||||
      command.options.connection = connection;
 | 
			
		||||
      // Execute the next command
 | 
			
		||||
      command.executeInsertCommand(command.db, command.db_command, command.options, command.callback);
 | 
			
		||||
    }  
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Internal class for authentication storage
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
var AuthStore = function() {
 | 
			
		||||
  var _auths = [];
 | 
			
		||||
 | 
			
		||||
  this.add = function(authMechanism, dbName, username, password, authdbName, gssapiServiceName) {
 | 
			
		||||
    // Check for duplicates
 | 
			
		||||
    if(!this.contains(dbName)) {
 | 
			
		||||
      // Base config
 | 
			
		||||
      var config = {
 | 
			
		||||
          'username':username
 | 
			
		||||
        , 'password':password
 | 
			
		||||
        , 'db': dbName
 | 
			
		||||
        , 'authMechanism': authMechanism
 | 
			
		||||
        , 'gssapiServiceName': gssapiServiceName
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      // Add auth source if passed in
 | 
			
		||||
      if(typeof authdbName == 'string') {
 | 
			
		||||
        config['authdb'] = authdbName;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Push the config
 | 
			
		||||
      _auths.push(config);
 | 
			
		||||
    }
 | 
			
		||||
  }  
 | 
			
		||||
 | 
			
		||||
  this.contains = function(dbName) {
 | 
			
		||||
    for(var i = 0; i < _auths.length; i++) {
 | 
			
		||||
      if(_auths[i].db == dbName) return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.remove = function(dbName) {
 | 
			
		||||
    var newAuths = [];
 | 
			
		||||
 | 
			
		||||
    // Filter out all the login details
 | 
			
		||||
    for(var i = 0; i < _auths.length; i++) {
 | 
			
		||||
      if(_auths[i].db != dbName) newAuths.push(_auths[i]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //  Set the filtered list
 | 
			
		||||
    _auths = newAuths;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.get = function(index) {
 | 
			
		||||
    return _auths[index];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.length = function() {
 | 
			
		||||
    return _auths.length;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.toArray = function() {
 | 
			
		||||
    return _auths.slice(0);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Internal class for storing db references
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
var DbStore = function() {
 | 
			
		||||
  var _dbs = [];
 | 
			
		||||
 | 
			
		||||
  this.add = function(db) {
 | 
			
		||||
    var found = false;
 | 
			
		||||
    
 | 
			
		||||
    // Only add if it does not exist already
 | 
			
		||||
    for(var i = 0; i < _dbs.length; i++) {
 | 
			
		||||
      if(db.databaseName == _dbs[i].databaseName) found = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Only add if it does not already exist
 | 
			
		||||
    if(!found) {
 | 
			
		||||
      _dbs.push(db);    
 | 
			
		||||
    } 
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.reset = function() {
 | 
			
		||||
    _dbs = [];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.db = function() {
 | 
			
		||||
    return _dbs;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.fetch = function(databaseName) {
 | 
			
		||||
    // Only add if it does not exist already
 | 
			
		||||
    for(var i = 0; i < _dbs.length; i++) {
 | 
			
		||||
      if(databaseName == _dbs[i].databaseName)
 | 
			
		||||
        return _dbs[i];
 | 
			
		||||
    }  
 | 
			
		||||
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.emit = function(event, message, object, reset, filterDb, rethrow_if_no_listeners) {
 | 
			
		||||
    var emitted = false;
 | 
			
		||||
 | 
			
		||||
    // Not emitted and we have enabled rethrow, let process.uncaughtException
 | 
			
		||||
    // deal with the issue
 | 
			
		||||
    if(!emitted && rethrow_if_no_listeners) {
 | 
			
		||||
      return process.nextTick(function() {
 | 
			
		||||
        throw message;      
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Emit the events
 | 
			
		||||
    for(var i = 0; i < _dbs.length; i++) {    
 | 
			
		||||
      if(_dbs[i].listeners(event).length > 0) {
 | 
			
		||||
        if(filterDb == null || filterDb.databaseName !== _dbs[i].databaseName 
 | 
			
		||||
          || filterDb.tag !== _dbs[i].tag) {
 | 
			
		||||
          _dbs[i].emit(event, message, object == null ? _dbs[i] : object);
 | 
			
		||||
          emitted = true;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Emit error message
 | 
			
		||||
    if(message 
 | 
			
		||||
      && event == 'error' 
 | 
			
		||||
      && !emitted
 | 
			
		||||
      && rethrow_if_no_listeners 
 | 
			
		||||
      && object && object.db) {
 | 
			
		||||
        process.nextTick(function() {
 | 
			
		||||
          object.db.emit(event, message, null);      
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var Base = function Base() {  
 | 
			
		||||
  EventEmitter.call(this);
 | 
			
		||||
 | 
			
		||||
  // Callback store is part of connection specification
 | 
			
		||||
  if(Base._callBackStore == null) {
 | 
			
		||||
    Base._callBackStore = new CallbackStore();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Create a new auth store
 | 
			
		||||
  var auth = new AuthStore();
 | 
			
		||||
 | 
			
		||||
  Object.defineProperty(this, "auth", {enumerable: true
 | 
			
		||||
    , get: function() { return auth; }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // Create a new callback store  
 | 
			
		||||
  this._callBackStore = new CallbackStore();
 | 
			
		||||
  // All commands not being executed
 | 
			
		||||
  this._commandsStore = new NonExecutedOperationStore(this);
 | 
			
		||||
  // Contains all the dbs attached to this server config
 | 
			
		||||
  this._dbStore = new DbStore();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
inherits(Base, EventEmitter);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Base.prototype._apply_auths = function(db, callback) {
 | 
			
		||||
  _apply_auths_serially(this, db, this.auth.toArray(), callback);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _apply_auths_serially = function(self, db, auths, callback) {
 | 
			
		||||
  if(auths.length == 0) return callback(null, null);
 | 
			
		||||
  // Get the first auth
 | 
			
		||||
  var auth = auths.shift();
 | 
			
		||||
  var connections = self.allRawConnections();
 | 
			
		||||
  var connectionsLeft = connections.length;
 | 
			
		||||
  var options = {};
 | 
			
		||||
 | 
			
		||||
  if(auth.authMechanism == 'GSSAPI') {
 | 
			
		||||
    // We have the kerberos library, execute auth process
 | 
			
		||||
    if(process.platform == 'win32') {
 | 
			
		||||
      mongodb_sspi_authenticate(db, auth.username, auth.password, auth.authdb, options, callback);
 | 
			
		||||
    } else {
 | 
			
		||||
      mongodb_gssapi_authenticate(db, auth.username, auth.password, auth.authdb, options, callback);
 | 
			
		||||
    }
 | 
			
		||||
  } else if(auth.authMechanism == 'MONGODB-CR') {
 | 
			
		||||
    mongodb_cr_authenticate(db, auth.username, auth.password, auth.authdb, options, callback);
 | 
			
		||||
  } else if(auth.authMechanism == 'SCRAM-SHA-1') {
 | 
			
		||||
    mongodb_scram_authenticate(db, auth.username, auth.password, auth.authdb, options, callback);
 | 
			
		||||
  } else if(auth.authMechanism == 'PLAIN') {
 | 
			
		||||
    mongodb_plain_authenticate(db, auth.username, auth.password, options, callback);
 | 
			
		||||
  } else if(auth.authMechanism == 'MONGODB-X509') {
 | 
			
		||||
    mongodb_x509_authenticate(db, auth.username, auth.password, options, callback);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Fire all the errors
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Base.prototype.__executeAllCallbacksWithError = function(err) {
 | 
			
		||||
  // Check all callbacks
 | 
			
		||||
  var keys = Object.keys(this._callBackStore._notReplied);
 | 
			
		||||
  // For each key check if it's a callback that needs to be returned
 | 
			
		||||
  for(var j = 0; j < keys.length; j++) {
 | 
			
		||||
    var info = this._callBackStore._notReplied[keys[j]];
 | 
			
		||||
    // Execute callback with error
 | 
			
		||||
    this._callBackStore.emit(keys[j], err, null);
 | 
			
		||||
    // Remove the key
 | 
			
		||||
    delete this._callBackStore._notReplied[keys[j]];
 | 
			
		||||
    // Force cleanup _events, node.js seems to set it as a null value
 | 
			
		||||
    if(this._callBackStore._events) {
 | 
			
		||||
      delete this._callBackStore._events[keys[j]];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Fire all the errors
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Base.prototype.__executeAllServerSpecificErrorCallbacks = function(host, port, err) {  
 | 
			
		||||
  // Check all callbacks
 | 
			
		||||
  var keys = Object.keys(this._callBackStore._notReplied);
 | 
			
		||||
  // For each key check if it's a callback that needs to be returned
 | 
			
		||||
  for(var j = 0; j < keys.length; j++) {
 | 
			
		||||
    var info = this._callBackStore._notReplied[keys[j]];
 | 
			
		||||
 | 
			
		||||
    if(info && info.connection) {
 | 
			
		||||
      // Unpack the connection settings
 | 
			
		||||
      var _host = info.connection.socketOptions.host;
 | 
			
		||||
      var _port = info.connection.socketOptions.port;
 | 
			
		||||
      // If the server matches execute the callback with the error
 | 
			
		||||
      if(_port == port && _host == host) {
 | 
			
		||||
        this._callBackStore.emit(keys[j], err, null);
 | 
			
		||||
        // Remove the key
 | 
			
		||||
        delete this._callBackStore._notReplied[keys[j]];
 | 
			
		||||
        // Force cleanup _events, node.js seems to set it as a null value
 | 
			
		||||
        if(this._callBackStore._events) {
 | 
			
		||||
          delete this._callBackStore._events[keys[j]];
 | 
			
		||||
        } 
 | 
			
		||||
      }      
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Register a handler
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
Base.prototype._registerHandler = function(db_command, raw, connection, exhaust, callback) {
 | 
			
		||||
  // Check if we have exhausted
 | 
			
		||||
  if(typeof exhaust == 'function') {
 | 
			
		||||
    callback = exhaust;
 | 
			
		||||
    exhaust = false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Add the callback to the list of handlers
 | 
			
		||||
  this._callBackStore.once(db_command.getRequestId(), callback);
 | 
			
		||||
  // Add the information about the reply
 | 
			
		||||
  this._callBackStore._notReplied[db_command.getRequestId().toString()] = {start: new Date().getTime(), 'raw': raw, connection:connection, exhaust:exhaust};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Re-Register a handler, on the cursor id f.ex
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
Base.prototype._reRegisterHandler = function(newId, object, callback) {
 | 
			
		||||
  // Add the callback to the list of handlers
 | 
			
		||||
  this._callBackStore.once(newId, object.callback.listener);
 | 
			
		||||
  // Add the information about the reply
 | 
			
		||||
  this._callBackStore._notReplied[newId] = object.info;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
Base.prototype._flushAllCallHandlers = function(err) {
 | 
			
		||||
  var keys = Object.keys(this._callBackStore._notReplied);
 | 
			
		||||
 | 
			
		||||
  for(var i = 0; i < keys.length; i++) {
 | 
			
		||||
    this._callHandler(keys[i], null, err);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
Base.prototype._callHandler = function(id, document, err) {
 | 
			
		||||
  var self = this;
 | 
			
		||||
 | 
			
		||||
  // If there is a callback peform it
 | 
			
		||||
  if(this._callBackStore.listeners(id).length >= 1) {
 | 
			
		||||
    // Get info object
 | 
			
		||||
    var info = this._callBackStore._notReplied[id];
 | 
			
		||||
    // Delete the current object
 | 
			
		||||
    delete this._callBackStore._notReplied[id]; 
 | 
			
		||||
    // Call the handle directly don't emit
 | 
			
		||||
    var callback = this._callBackStore.listeners(id)[0].listener;
 | 
			
		||||
    // Remove the listeners
 | 
			
		||||
    this._callBackStore.removeAllListeners(id);
 | 
			
		||||
    // Force key deletion because it nulling it not deleting in 0.10.X
 | 
			
		||||
    if(this._callBackStore._events) {
 | 
			
		||||
      delete this._callBackStore._events[id];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      // Execute the callback if one was provided
 | 
			
		||||
      if(typeof callback == 'function') callback(err, document, info.connection);
 | 
			
		||||
    } catch(err) {
 | 
			
		||||
      self._emitAcrossAllDbInstances(self, null, "error", utils.toError(err), self, true, true);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
Base.prototype._hasHandler = function(id) {
 | 
			
		||||
  return this._callBackStore.listeners(id).length >= 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
Base.prototype._removeHandler = function(id) {
 | 
			
		||||
  // Remove the information
 | 
			
		||||
  if(this._callBackStore._notReplied[id] != null) delete this._callBackStore._notReplied[id];
 | 
			
		||||
  // Remove the callback if it's registered
 | 
			
		||||
  this._callBackStore.removeAllListeners(id);
 | 
			
		||||
  // Force cleanup _events, node.js seems to set it as a null value
 | 
			
		||||
  if(this._callBackStore._events) {
 | 
			
		||||
    delete this._callBackStore._events[id];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
Base.prototype._findHandler = function(id) {
 | 
			
		||||
  var info = this._callBackStore._notReplied[id];
 | 
			
		||||
  // Return the callback
 | 
			
		||||
  return {info:info, callback:(this._callBackStore.listeners(id).length >= 1) ? this._callBackStore.listeners(id)[0] : null}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
Base.prototype._emitAcrossAllDbInstances = function(server, filterDb, event, message, object, resetConnection, rethrow_if_no_listeners) {
 | 
			
		||||
  if(resetConnection) {
 | 
			
		||||
    var dbs = this._dbStore.db();
 | 
			
		||||
 | 
			
		||||
    for(var i = 0; i < dbs.length; i++) {
 | 
			
		||||
      if(typeof dbs[i].openCalled != 'undefined')
 | 
			
		||||
        dbs[i].openCalled = false;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Fire event
 | 
			
		||||
  this._dbStore.emit(event, message, object, resetConnection, filterDb, rethrow_if_no_listeners);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.Base = Base;
 | 
			
		||||
							
								
								
									
										563
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/connection.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										563
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/connection.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,563 @@
 | 
			
		||||
var utils = require('./connection_utils'),
 | 
			
		||||
  inherits = require('util').inherits,
 | 
			
		||||
  net = require('net'),
 | 
			
		||||
  EventEmitter = require('events').EventEmitter,
 | 
			
		||||
  inherits = require('util').inherits,
 | 
			
		||||
  binaryutils = require('../utils'),
 | 
			
		||||
  tls = require('tls');
 | 
			
		||||
 | 
			
		||||
var Connection = exports.Connection = function(id, socketOptions) {
 | 
			
		||||
  var self = this;
 | 
			
		||||
  // Set up event emitter
 | 
			
		||||
  EventEmitter.call(this);
 | 
			
		||||
  // Store all socket options
 | 
			
		||||
  this.socketOptions = socketOptions ? socketOptions : {host:'localhost', port:27017, domainSocket:false};
 | 
			
		||||
  // Set keep alive default if not overriden
 | 
			
		||||
  if(this.socketOptions.keepAlive == null && !(process.platform == "sunos" || process.platform == "win32")) this.socketOptions.keepAlive = 100;
 | 
			
		||||
  // Id for the connection
 | 
			
		||||
  this.id = id;
 | 
			
		||||
  // State of the connection
 | 
			
		||||
  this.connected = false;
 | 
			
		||||
  // Set if this is a domain socket
 | 
			
		||||
  this.domainSocket = this.socketOptions.domainSocket;
 | 
			
		||||
 | 
			
		||||
  // Supported min and max wire protocol
 | 
			
		||||
  this.minWireVersion = 0;
 | 
			
		||||
  this.maxWireVersion = 3;
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // Connection parsing state
 | 
			
		||||
  //
 | 
			
		||||
  this.maxBsonSize = socketOptions.maxBsonSize ? socketOptions.maxBsonSize : Connection.DEFAULT_MAX_BSON_SIZE;
 | 
			
		||||
  this.maxMessageSizeBytes = socketOptions.maxMessageSizeBytes ? socketOptions.maxMessageSizeBytes : Connection.DEFAULT_MAX_MESSAGE_SIZE;
 | 
			
		||||
  this.maxNumberOfDocsInBatch = socketOptions.maxWriteBatchSize ? socketOptions.maxWriteBatchSize : Connection.DEFAULT_MAX_WRITE_BATCH_SIZE;
 | 
			
		||||
  // Contains the current message bytes
 | 
			
		||||
  this.buffer = null;
 | 
			
		||||
  // Contains the current message size
 | 
			
		||||
  this.sizeOfMessage = 0;
 | 
			
		||||
  // Contains the readIndex for the messaage
 | 
			
		||||
  this.bytesRead = 0;
 | 
			
		||||
  // Contains spill over bytes from additional messages
 | 
			
		||||
  this.stubBuffer = 0;
 | 
			
		||||
 | 
			
		||||
  // Just keeps list of events we allow
 | 
			
		||||
  this.eventHandlers = {error:[], parseError:[], poolReady:[], message:[], close:[], timeout:[], end:[]};
 | 
			
		||||
 | 
			
		||||
  // Just keeps list of events we allow
 | 
			
		||||
  resetHandlers(this, false);
 | 
			
		||||
  
 | 
			
		||||
  // Bson object
 | 
			
		||||
  this.maxBsonSettings = {
 | 
			
		||||
      disableDriverBSONSizeCheck: this.socketOptions['disableDriverBSONSizeCheck'] || false
 | 
			
		||||
    , maxBsonSize: this.maxBsonSize
 | 
			
		||||
    , maxMessageSizeBytes: this.maxMessageSizeBytes
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Allow setting the socketTimeoutMS on all connections
 | 
			
		||||
  // to work around issues such as secondaries blocking due to compaction
 | 
			
		||||
  Object.defineProperty(this, "socketTimeoutMS", {
 | 
			
		||||
      enumerable: true
 | 
			
		||||
    , get: function () { return self.socketOptions.socketTimeoutMS; }
 | 
			
		||||
    , set: function (value) { 
 | 
			
		||||
      // Set the socket timeoutMS value
 | 
			
		||||
      self.socketOptions.socketTimeoutMS = value;
 | 
			
		||||
      // Set the physical connection timeout
 | 
			
		||||
      self.connection.setTimeout(self.socketOptions.socketTimeoutMS);
 | 
			
		||||
    }
 | 
			
		||||
  });  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Set max bson size
 | 
			
		||||
Connection.DEFAULT_MAX_BSON_SIZE = 1024 * 1024 * 4;
 | 
			
		||||
// Set default to max bson to avoid overflow or bad guesses
 | 
			
		||||
Connection.DEFAULT_MAX_MESSAGE_SIZE = Connection.DEFAULT_MAX_BSON_SIZE;
 | 
			
		||||
// Max default write bulk ops
 | 
			
		||||
Connection.DEFAULT_MAX_WRITE_BATCH_SIZE = 2000;
 | 
			
		||||
 | 
			
		||||
// Inherit event emitter so we can emit stuff wohoo
 | 
			
		||||
inherits(Connection, EventEmitter);
 | 
			
		||||
 | 
			
		||||
Connection.prototype.start = function() {
 | 
			
		||||
  var self = this;
 | 
			
		||||
 | 
			
		||||
  // If we have a normal connection
 | 
			
		||||
  if(this.socketOptions.ssl) {
 | 
			
		||||
    // Create new connection instance
 | 
			
		||||
    if(this.domainSocket) {
 | 
			
		||||
      this.connection = net.createConnection(this.socketOptions.host);
 | 
			
		||||
    } else {
 | 
			
		||||
      this.connection = net.createConnection(this.socketOptions.port, this.socketOptions.host);
 | 
			
		||||
    }
 | 
			
		||||
    if(this.logger != null && this.logger.doDebug){
 | 
			
		||||
      this.logger.debug("opened connection", this.socketOptions);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Set options on the socket
 | 
			
		||||
    this.connection.setTimeout(this.socketOptions.connectTimeoutMS != null ? this.socketOptions.connectTimeoutMS : this.socketOptions.timeout);
 | 
			
		||||
    // Work around for 0.4.X
 | 
			
		||||
    if(process.version.indexOf("v0.4") == -1) this.connection.setNoDelay(this.socketOptions.noDelay);
 | 
			
		||||
    // Set keep alive if defined
 | 
			
		||||
    if(process.version.indexOf("v0.4") == -1) {
 | 
			
		||||
      if(this.socketOptions.keepAlive > 0) {
 | 
			
		||||
        this.connection.setKeepAlive(true, this.socketOptions.keepAlive);
 | 
			
		||||
      } else {
 | 
			
		||||
        this.connection.setKeepAlive(false);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Check if the driver should validate the certificate
 | 
			
		||||
    var validate_certificates = this.socketOptions.sslValidate == true ? true : false;
 | 
			
		||||
 | 
			
		||||
    // Create options for the tls connection
 | 
			
		||||
    var tls_options = {
 | 
			
		||||
        socket: this.connection
 | 
			
		||||
      , rejectUnauthorized: false
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If we wish to validate the certificate we have provided a ca store
 | 
			
		||||
    if(validate_certificates) {
 | 
			
		||||
      tls_options.ca = this.socketOptions.sslCA;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If we have a certificate to present
 | 
			
		||||
    if(this.socketOptions.sslCert) {      
 | 
			
		||||
      tls_options.cert = this.socketOptions.sslCert;
 | 
			
		||||
      tls_options.key = this.socketOptions.sslKey;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If the driver has been provided a private key password
 | 
			
		||||
    if(this.socketOptions.sslPass) {
 | 
			
		||||
      tls_options.passphrase = this.socketOptions.sslPass;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Contains the cleartext stream
 | 
			
		||||
    var cleartext = null;
 | 
			
		||||
    // Attempt to establish a TLS connection to the server
 | 
			
		||||
    try {
 | 
			
		||||
      cleartext = tls.connect(this.socketOptions.port, this.socketOptions.host, tls_options, function() {      
 | 
			
		||||
        // If we have a ssl certificate validation error return an error
 | 
			
		||||
        if(cleartext.authorizationError && validate_certificates) {          
 | 
			
		||||
          // Emit an error
 | 
			
		||||
          return self.emit("error", cleartext.authorizationError, self, {ssl:true});        
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // Connect to the server
 | 
			
		||||
        connectHandler(self)();
 | 
			
		||||
      })      
 | 
			
		||||
    } catch(err) {
 | 
			
		||||
      return self.emit("error", "SSL connection failed", self, {ssl:true});
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Save the output stream
 | 
			
		||||
    this.writeSteam = cleartext;
 | 
			
		||||
 | 
			
		||||
    // Set up data handler for the clear stream
 | 
			
		||||
    cleartext.on("data", createDataHandler(this));
 | 
			
		||||
    // Do any handling of end event of the stream
 | 
			
		||||
    cleartext.on("end", endHandler(this));
 | 
			
		||||
    cleartext.on("error", errorHandler(this));    
 | 
			
		||||
 | 
			
		||||
    // Handle any errors
 | 
			
		||||
    this.connection.on("error", errorHandler(this));    
 | 
			
		||||
    // Handle timeout
 | 
			
		||||
    this.connection.on("timeout", timeoutHandler(this));
 | 
			
		||||
    // Handle drain event
 | 
			
		||||
    this.connection.on("drain", drainHandler(this));
 | 
			
		||||
    // Handle the close event
 | 
			
		||||
    this.connection.on("close", closeHandler(this));
 | 
			
		||||
  } else {
 | 
			
		||||
    // Create new connection instance
 | 
			
		||||
    if(this.domainSocket) {
 | 
			
		||||
      this.connection = net.createConnection(this.socketOptions.host);
 | 
			
		||||
    } else {
 | 
			
		||||
      this.connection = net.createConnection(this.socketOptions.port, this.socketOptions.host);
 | 
			
		||||
    }
 | 
			
		||||
    if(this.logger != null && this.logger.doDebug){
 | 
			
		||||
      this.logger.debug("opened connection", this.socketOptions);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Set options on the socket
 | 
			
		||||
    this.connection.setTimeout(this.socketOptions.connectTimeoutMS != null ? this.socketOptions.connectTimeoutMS : this.socketOptions.timeout);
 | 
			
		||||
    // Work around for 0.4.X
 | 
			
		||||
    if(process.version.indexOf("v0.4") == -1) this.connection.setNoDelay(this.socketOptions.noDelay);
 | 
			
		||||
    // Set keep alive if defined
 | 
			
		||||
    if(process.version.indexOf("v0.4") == -1) {
 | 
			
		||||
      if(this.socketOptions.keepAlive > 0) {
 | 
			
		||||
        this.connection.setKeepAlive(true, this.socketOptions.keepAlive);
 | 
			
		||||
      } else {
 | 
			
		||||
        this.connection.setKeepAlive(false);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Set up write stream
 | 
			
		||||
    this.writeSteam = this.connection;
 | 
			
		||||
    // Add handlers
 | 
			
		||||
    this.connection.on("error", errorHandler(this));
 | 
			
		||||
    // Add all handlers to the socket to manage it
 | 
			
		||||
    this.connection.on("connect", connectHandler(this));
 | 
			
		||||
    // this.connection.on("end", endHandler(this));
 | 
			
		||||
    this.connection.on("data", createDataHandler(this));
 | 
			
		||||
    this.connection.on("timeout", timeoutHandler(this));
 | 
			
		||||
    this.connection.on("drain", drainHandler(this));
 | 
			
		||||
    this.connection.on("close", closeHandler(this));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Connection.prototype.setSocketOptions = function(options) {
 | 
			
		||||
  options = options || {};
 | 
			
		||||
 | 
			
		||||
  if(typeof options.connectTimeoutMS == 'number') {
 | 
			
		||||
    this.socketOptions.connectTimeoutMS = options.connectTimeoutMS;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(typeof options.socketTimeoutMS == 'number') {
 | 
			
		||||
    this.socketOptions.socketTimeoutMS = options.socketTimeoutMS;
 | 
			
		||||
    // Set the current socket timeout
 | 
			
		||||
    this.connection.setTimeout(options.socketTimeoutMS);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Check if the sockets are live
 | 
			
		||||
Connection.prototype.isConnected = function() {
 | 
			
		||||
  return this.connected && !this.connection.destroyed && this.connection.writable;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Validate if the driver supports this server
 | 
			
		||||
Connection.prototype.isCompatible = function() {
 | 
			
		||||
  if(this.serverCapabilities == null) return true;
 | 
			
		||||
 | 
			
		||||
  // Is compatible with backward server
 | 
			
		||||
  if(this.serverCapabilities.minWireVersion == 0 
 | 
			
		||||
    && this.serverCapabilities.maxWireVersion ==0) return true;
 | 
			
		||||
 | 
			
		||||
  // Check if we overlap
 | 
			
		||||
  if(this.serverCapabilities.minWireVersion >= this.minWireVersion
 | 
			
		||||
    && this.serverCapabilities.maxWireVersion <= this.maxWireVersion) return true;
 | 
			
		||||
 | 
			
		||||
  // Not compatible
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Write the data out to the socket
 | 
			
		||||
Connection.prototype.write = function(command, callback) {
 | 
			
		||||
  try {
 | 
			
		||||
    // If we have a list off commands to be executed on the same socket
 | 
			
		||||
    if(Array.isArray(command)) {
 | 
			
		||||
      for(var i = 0; i < command.length; i++) {
 | 
			
		||||
        try {
 | 
			
		||||
          // Pass in the bson validation settings (validate early)
 | 
			
		||||
          var binaryCommand = command[i].toBinary(this.maxBsonSettings);
 | 
			
		||||
 | 
			
		||||
          if(this.logger != null && this.logger.doDebug) 
 | 
			
		||||
            this.logger.debug("writing command to mongodb", {binary: binaryCommand, json: command[i]});
 | 
			
		||||
 | 
			
		||||
          this.writeSteam.write(binaryCommand);
 | 
			
		||||
        } catch(err) {
 | 
			
		||||
          return callback(err, null);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      try {
 | 
			
		||||
        // Pass in the bson validation settings (validate early)
 | 
			
		||||
        var binaryCommand = command.toBinary(this.maxBsonSettings);
 | 
			
		||||
        // Do we have a logger active log the event
 | 
			
		||||
        if(this.logger != null && this.logger.doDebug) 
 | 
			
		||||
          this.logger.debug("writing command to mongodb", {binary: binaryCommand, json: command});
 | 
			
		||||
        // Write the binary command out to socket
 | 
			
		||||
        this.writeSteam.write(binaryCommand);
 | 
			
		||||
      } catch(err) {
 | 
			
		||||
        return callback(err, null);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  } catch (err) {
 | 
			
		||||
    if(typeof callback === 'function') callback(err);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Force the closure of the connection
 | 
			
		||||
Connection.prototype.close = function() {
 | 
			
		||||
  // clear out all the listeners
 | 
			
		||||
  resetHandlers(this, true);
 | 
			
		||||
  // Add a dummy error listener to catch any weird last moment errors (and ignore them)
 | 
			
		||||
  this.connection.on("error", function() {})
 | 
			
		||||
  // destroy connection
 | 
			
		||||
  this.connection.destroy();
 | 
			
		||||
  if(this.logger != null && this.logger.doDebug){
 | 
			
		||||
    this.logger.debug("closed connection", this.connection);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Reset all handlers
 | 
			
		||||
var resetHandlers = function(self, clearListeners) {
 | 
			
		||||
  self.eventHandlers = {error:[], connect:[], close:[], end:[], timeout:[], parseError:[], message:[]};
 | 
			
		||||
 | 
			
		||||
  // If we want to clear all the listeners
 | 
			
		||||
  if(clearListeners && self.connection != null) {
 | 
			
		||||
    var keys = Object.keys(self.eventHandlers);
 | 
			
		||||
    // Remove all listeners
 | 
			
		||||
    for(var i = 0; i < keys.length; i++) {
 | 
			
		||||
      self.connection.removeAllListeners(keys[i]);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Handlers
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// Connect handler
 | 
			
		||||
var connectHandler = function(self) {
 | 
			
		||||
  return function(data) {
 | 
			
		||||
    // Set connected
 | 
			
		||||
    self.connected = true;
 | 
			
		||||
    // Now that we are connected set the socket timeout
 | 
			
		||||
    self.connection.setTimeout(self.socketOptions.socketTimeoutMS != null ? self.socketOptions.socketTimeoutMS : self.socketOptions.timeout);
 | 
			
		||||
    // Emit the connect event with no error
 | 
			
		||||
    self.emit("connect", null, self);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var createDataHandler = exports.Connection.createDataHandler = function(self) {
 | 
			
		||||
  // We need to handle the parsing of the data
 | 
			
		||||
  // and emit the messages when there is a complete one
 | 
			
		||||
  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.emit("message", emitBuffer, self);
 | 
			
		||||
          } catch(err) {
 | 
			
		||||
            var errorObject = {err:"socketHandler", trace:err, bin:self.buffer, parseState:{
 | 
			
		||||
              sizeOfMessage:self.sizeOfMessage,
 | 
			
		||||
              bytesRead:self.bytesRead,
 | 
			
		||||
              stubBuffer:self.stubBuffer}};
 | 
			
		||||
            if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject);
 | 
			
		||||
            // 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 = binaryutils.decodeUInt32(data, 0);
 | 
			
		||||
            // If we have a negative sizeOfMessage emit error and return
 | 
			
		||||
            if(sizeOfMessage < 0 || sizeOfMessage > self.maxMessageSizeBytes) {
 | 
			
		||||
              var errorObject = {err:"socketHandler", trace:'', bin:self.buffer, parseState:{
 | 
			
		||||
                sizeOfMessage: sizeOfMessage,
 | 
			
		||||
                bytesRead: self.bytesRead,
 | 
			
		||||
                stubBuffer: self.stubBuffer}};
 | 
			
		||||
              if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject);
 | 
			
		||||
              // 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.maxMessageSizeBytes && 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.maxMessageSizeBytes && 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.emit("message", emitBuffer, self);
 | 
			
		||||
              } catch (err) {
 | 
			
		||||
                var errorObject = {err:"socketHandler", trace:err, bin:self.buffer, parseState:{
 | 
			
		||||
                  sizeOfMessage:self.sizeOfMessage,
 | 
			
		||||
                  bytesRead:self.bytesRead,
 | 
			
		||||
                  stubBuffer:self.stubBuffer}};
 | 
			
		||||
                if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject);
 | 
			
		||||
                // We got a parse Error fire it off then keep going
 | 
			
		||||
                self.emit("parseError", errorObject, self);
 | 
			
		||||
              }
 | 
			
		||||
            } else if(sizeOfMessage <= 4 || sizeOfMessage > self.maxMessageSizeBytes) {
 | 
			
		||||
              var errorObject = {err:"socketHandler", trace:null, bin:data, parseState:{
 | 
			
		||||
                sizeOfMessage:sizeOfMessage,
 | 
			
		||||
                bytesRead:0,
 | 
			
		||||
                buffer:null,
 | 
			
		||||
                stubBuffer:null}};
 | 
			
		||||
              if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject);
 | 
			
		||||
              // 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 {
 | 
			
		||||
              try {
 | 
			
		||||
                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.emit("message", emitBuffer, self);
 | 
			
		||||
              } catch (err) {
 | 
			
		||||
                var errorObject = {err:"socketHandler", trace:err, bin:self.buffer, parseState:{
 | 
			
		||||
                  sizeOfMessage:sizeOfMessage,
 | 
			
		||||
                  bytesRead:self.bytesRead,
 | 
			
		||||
                  stubBuffer:self.stubBuffer}};
 | 
			
		||||
                if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject);
 | 
			
		||||
                // We got a parse Error fire it off then keep going
 | 
			
		||||
                self.emit("parseError", errorObject, 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);
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var endHandler = function(self) {
 | 
			
		||||
  return function() {
 | 
			
		||||
    // Set connected to false
 | 
			
		||||
    self.connected = false;
 | 
			
		||||
    // Emit end event
 | 
			
		||||
    self.emit("end", {err: 'connection received Fin packet from [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var timeoutHandler = function(self) {
 | 
			
		||||
  return function() {
 | 
			
		||||
    // Set connected to false
 | 
			
		||||
    self.connected = false;
 | 
			
		||||
    // Emit timeout event
 | 
			
		||||
    self.emit("timeout", {err: 'connection to [' + self.socketOptions.host + ':' + self.socketOptions.port + '] timed out'}, self);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var drainHandler = function(self) {
 | 
			
		||||
  return function() {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var errorHandler = function(self) {
 | 
			
		||||
  return function(err) {
 | 
			
		||||
    self.connection.destroy();
 | 
			
		||||
    // Set connected to false
 | 
			
		||||
    self.connected = false;
 | 
			
		||||
    // Emit error
 | 
			
		||||
    self.emit("error", {err: 'failed to connect to [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var closeHandler = function(self) {
 | 
			
		||||
  return function(hadError) {
 | 
			
		||||
    // If we have an error during the connection phase
 | 
			
		||||
    if(hadError && !self.connected) {
 | 
			
		||||
      // Set disconnected
 | 
			
		||||
      self.connected = false;
 | 
			
		||||
      // Emit error
 | 
			
		||||
      self.emit("error", {err: 'failed to connect to [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self);
 | 
			
		||||
    } else {
 | 
			
		||||
      // Set disconnected
 | 
			
		||||
      self.connected = false;
 | 
			
		||||
      // Emit close
 | 
			
		||||
      self.emit("close", {err: 'connection closed to [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Some basic defaults
 | 
			
		||||
Connection.DEFAULT_PORT = 27017;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										311
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/connection_pool.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										311
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/connection_pool.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,311 @@
 | 
			
		||||
var utils = require('./connection_utils'),
 | 
			
		||||
  inherits = require('util').inherits,
 | 
			
		||||
  net = require('net'),
 | 
			
		||||
  timers = require('timers'),
 | 
			
		||||
  EventEmitter = require('events').EventEmitter,
 | 
			
		||||
  inherits = require('util').inherits,
 | 
			
		||||
  MongoReply = require("../responses/mongo_reply").MongoReply,
 | 
			
		||||
  Connection = require("./connection").Connection;
 | 
			
		||||
 | 
			
		||||
// Set processor, setImmediate if 0.10 otherwise nextTick
 | 
			
		||||
var processor = require('../utils').processor();
 | 
			
		||||
 | 
			
		||||
var ConnectionPool = exports.ConnectionPool = function(host, port, poolSize, bson, socketOptions) {
 | 
			
		||||
  if(typeof host !== 'string') {
 | 
			
		||||
    throw new Error("host must be specified [" + host + "]");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Set up event emitter
 | 
			
		||||
  EventEmitter.call(this);
 | 
			
		||||
 | 
			
		||||
  // Keep all options for the socket in a specific collection allowing the user to specify the
 | 
			
		||||
  // Wished upon socket connection parameters
 | 
			
		||||
  this.socketOptions = typeof socketOptions === 'object' ? socketOptions : {};
 | 
			
		||||
  this.socketOptions.host = host;
 | 
			
		||||
  this.socketOptions.port = port;
 | 
			
		||||
  this.socketOptions.domainSocket = false;
 | 
			
		||||
  this.bson = bson;
 | 
			
		||||
  // PoolSize is always + 1 for special reserved "measurment" socket (like ping, stats etc)
 | 
			
		||||
  if (typeof poolSize !== 'number') {
 | 
			
		||||
    poolSize = parseInt(poolSize.toString(), 10);
 | 
			
		||||
    if (isNaN(poolSize)) {
 | 
			
		||||
      throw new Error("poolSize must be a number!");
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  this.poolSize = poolSize;
 | 
			
		||||
  this.minPoolSize = Math.floor(this.poolSize / 2) + 1;
 | 
			
		||||
 | 
			
		||||
  // Check if the host is a socket
 | 
			
		||||
  if(host.match(/^\//)) {
 | 
			
		||||
    this.socketOptions.domainSocket = true;
 | 
			
		||||
  } else if(typeof port === 'string') {
 | 
			
		||||
    try { 
 | 
			
		||||
      port = parseInt(port, 10); 
 | 
			
		||||
    } catch(err) { 
 | 
			
		||||
      new Error("port must be specified or valid integer["  + port + "]"); 
 | 
			
		||||
    }
 | 
			
		||||
  } else if(typeof port !== 'number') {
 | 
			
		||||
    throw new Error("port must be specified ["  + port + "]");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Set default settings for the socket options
 | 
			
		||||
  utils.setIntegerParameter(this.socketOptions, 'timeout', 0);
 | 
			
		||||
  // Delay before writing out the data to the server
 | 
			
		||||
  utils.setBooleanParameter(this.socketOptions, 'noDelay', true);
 | 
			
		||||
  // Delay before writing out the data to the server
 | 
			
		||||
  utils.setIntegerParameter(this.socketOptions, 'keepAlive', 0);
 | 
			
		||||
  // Set the encoding of the data read, default is binary == null
 | 
			
		||||
  utils.setStringParameter(this.socketOptions, 'encoding', null);
 | 
			
		||||
  // Allows you to set a throttling bufferSize if you need to stop overflows
 | 
			
		||||
  utils.setIntegerParameter(this.socketOptions, 'bufferSize', 0);
 | 
			
		||||
 | 
			
		||||
  // Internal structures
 | 
			
		||||
  this.openConnections = [];
 | 
			
		||||
  // Assign connection id's
 | 
			
		||||
  this.connectionId = 0;
 | 
			
		||||
 | 
			
		||||
  // Current index for selection of pool connection
 | 
			
		||||
  this.currentConnectionIndex = 0;
 | 
			
		||||
  // The pool state
 | 
			
		||||
  this._poolState = 'disconnected';
 | 
			
		||||
  // timeout control
 | 
			
		||||
  this._timeout = false;
 | 
			
		||||
  // Time to wait between connections for the pool
 | 
			
		||||
  this._timeToWait = 10;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inherits(ConnectionPool, EventEmitter);
 | 
			
		||||
 | 
			
		||||
ConnectionPool.prototype.setMaxBsonSize = function(maxBsonSize) {
 | 
			
		||||
  if(maxBsonSize == null){
 | 
			
		||||
    maxBsonSize = Connection.DEFAULT_MAX_BSON_SIZE;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for(var i = 0; i < this.openConnections.length; i++) {
 | 
			
		||||
    this.openConnections[i].maxBsonSize = maxBsonSize;
 | 
			
		||||
    this.openConnections[i].maxBsonSettings.maxBsonSize = maxBsonSize;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ConnectionPool.prototype.setMaxMessageSizeBytes = function(maxMessageSizeBytes) {
 | 
			
		||||
  if(maxMessageSizeBytes == null){
 | 
			
		||||
    maxMessageSizeBytes = Connection.DEFAULT_MAX_MESSAGE_SIZE;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for(var i = 0; i < this.openConnections.length; i++) {
 | 
			
		||||
    this.openConnections[i].maxMessageSizeBytes = maxMessageSizeBytes;
 | 
			
		||||
    this.openConnections[i].maxBsonSettings.maxMessageSizeBytes = maxMessageSizeBytes;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ConnectionPool.prototype.setMaxWriteBatchSize = function(maxWriteBatchSize) {
 | 
			
		||||
  if(maxWriteBatchSize == null){
 | 
			
		||||
    maxWriteBatchSize = Connection.DEFAULT_MAX_WRITE_BATCH_SIZE;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for(var i = 0; i < this.openConnections.length; i++) {
 | 
			
		||||
    this.openConnections[i].maxWriteBatchSize = maxWriteBatchSize;
 | 
			
		||||
  }  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Start a function
 | 
			
		||||
var _connect = function(_self) {
 | 
			
		||||
  // return new function() {
 | 
			
		||||
    // Create a new connection instance
 | 
			
		||||
    var connection = new Connection(_self.connectionId++, _self.socketOptions);
 | 
			
		||||
    // Set logger on pool
 | 
			
		||||
    connection.logger = _self.logger;
 | 
			
		||||
    // Connect handler
 | 
			
		||||
    connection.on("connect", function(err, connection) {
 | 
			
		||||
      // Add connection to list of open connections
 | 
			
		||||
      _self.openConnections.push(connection);
 | 
			
		||||
      // If the number of open connections is equal to the poolSize signal ready pool
 | 
			
		||||
      if(_self.openConnections.length === _self.poolSize && _self._poolState !== 'disconnected') {
 | 
			
		||||
        // Set connected
 | 
			
		||||
        _self._poolState = 'connected';
 | 
			
		||||
        // Emit pool ready
 | 
			
		||||
        _self.emit("poolReady");
 | 
			
		||||
      } else if(_self.openConnections.length < _self.poolSize) {
 | 
			
		||||
        // Wait a little bit of time to let the close event happen if the server closes the connection
 | 
			
		||||
        // so we don't leave hanging connections around
 | 
			
		||||
        if(typeof _self._timeToWait == 'number') {
 | 
			
		||||
          setTimeout(function() {
 | 
			
		||||
            // If we are still connecting (no close events fired in between start another connection)
 | 
			
		||||
            if(_self._poolState == 'connecting') {
 | 
			
		||||
              _connect(_self);
 | 
			
		||||
            }
 | 
			
		||||
          }, _self._timeToWait);
 | 
			
		||||
        } else {
 | 
			
		||||
          processor(function() {
 | 
			
		||||
            // If we are still connecting (no close events fired in between start another connection)
 | 
			
		||||
            if(_self._poolState == 'connecting') {
 | 
			
		||||
              _connect(_self);
 | 
			
		||||
            }
 | 
			
		||||
          });
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    var numberOfErrors = 0
 | 
			
		||||
 | 
			
		||||
    // Error handler
 | 
			
		||||
    connection.on("error", function(err, connection, error_options) {
 | 
			
		||||
      numberOfErrors++;
 | 
			
		||||
      // If we are already disconnected ignore the event
 | 
			
		||||
      if(_self._poolState != 'disconnected' && _self.listeners("error").length > 0) {
 | 
			
		||||
        _self.emit("error", err, connection, error_options);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Close the connection
 | 
			
		||||
      connection.close();
 | 
			
		||||
      // Set pool as disconnected
 | 
			
		||||
      _self._poolState = 'disconnected';
 | 
			
		||||
      // Stop the pool
 | 
			
		||||
      _self.stop();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Close handler
 | 
			
		||||
    connection.on("close", function() {
 | 
			
		||||
      // If we are already disconnected ignore the event
 | 
			
		||||
      if(_self._poolState !== 'disconnected' && _self.listeners("close").length > 0) {
 | 
			
		||||
        _self.emit("close");
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Set disconnected
 | 
			
		||||
      _self._poolState = 'disconnected';
 | 
			
		||||
      // Stop
 | 
			
		||||
      _self.stop();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Timeout handler
 | 
			
		||||
    connection.on("timeout", function(err, connection) {
 | 
			
		||||
      // If we are already disconnected ignore the event
 | 
			
		||||
      if(_self._poolState !== 'disconnected' && _self.listeners("timeout").length > 0) {
 | 
			
		||||
        _self.emit("timeout", err);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Close the connection
 | 
			
		||||
      connection.close();
 | 
			
		||||
      // Set disconnected
 | 
			
		||||
      _self._poolState = 'disconnected';
 | 
			
		||||
      _self.stop();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Parse error, needs a complete shutdown of the pool
 | 
			
		||||
    connection.on("parseError", function() {
 | 
			
		||||
      // If we are already disconnected ignore the event
 | 
			
		||||
      if(_self._poolState !== 'disconnected' && _self.listeners("parseError").length > 0) {
 | 
			
		||||
        _self.emit("parseError", new Error("parseError occured"));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Set disconnected
 | 
			
		||||
      _self._poolState = 'disconnected';
 | 
			
		||||
      _self.stop();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    connection.on("message", function(message) {
 | 
			
		||||
      _self.emit("message", message);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Start connection in the next tick
 | 
			
		||||
    connection.start();
 | 
			
		||||
  // }();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Start method, will throw error if no listeners are available
 | 
			
		||||
// Pass in an instance of the listener that contains the api for
 | 
			
		||||
// finding callbacks for a given message etc.
 | 
			
		||||
ConnectionPool.prototype.start = function() {
 | 
			
		||||
  var markerDate = new Date().getTime();
 | 
			
		||||
  var self = this;
 | 
			
		||||
 | 
			
		||||
  if(this.listeners("poolReady").length == 0) {
 | 
			
		||||
    throw "pool must have at least one listener ready that responds to the [poolReady] event";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Set pool state to connecting
 | 
			
		||||
  this._poolState = 'connecting';
 | 
			
		||||
  this._timeout = false;
 | 
			
		||||
 | 
			
		||||
  _connect(self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Restart a connection pool (on a close the pool might be in a wrong state)
 | 
			
		||||
ConnectionPool.prototype.restart = function() {
 | 
			
		||||
  // Close all connections
 | 
			
		||||
  this.stop(false);
 | 
			
		||||
  // Now restart the pool
 | 
			
		||||
  this.start();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Stop the connections in the pool
 | 
			
		||||
ConnectionPool.prototype.stop = function(removeListeners) {
 | 
			
		||||
  removeListeners = removeListeners == null ? true : removeListeners;
 | 
			
		||||
  // Set disconnected
 | 
			
		||||
  this._poolState = 'disconnected';
 | 
			
		||||
 | 
			
		||||
  // Clear all listeners if specified
 | 
			
		||||
  if(removeListeners) {
 | 
			
		||||
    this.removeAllEventListeners();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Close all connections
 | 
			
		||||
  for(var i = 0; i < this.openConnections.length; i++) {
 | 
			
		||||
    this.openConnections[i].close();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Clean up
 | 
			
		||||
  this.openConnections = [];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Check the status of the connection
 | 
			
		||||
ConnectionPool.prototype.isConnected = function() {
 | 
			
		||||
  // return this._poolState === 'connected';
 | 
			
		||||
  return this.openConnections.length > 0 && this.openConnections[0].isConnected();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Checkout a connection from the pool for usage, or grab a specific pool instance
 | 
			
		||||
ConnectionPool.prototype.checkoutConnection = function(id) {
 | 
			
		||||
  var index = (this.currentConnectionIndex++ % (this.openConnections.length));
 | 
			
		||||
  var connection = this.openConnections[index];
 | 
			
		||||
  return connection;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ConnectionPool.prototype.getAllConnections = function() {
 | 
			
		||||
  return this.openConnections;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Remove all non-needed event listeners
 | 
			
		||||
ConnectionPool.prototype.removeAllEventListeners = function() {
 | 
			
		||||
  this.removeAllListeners("close");
 | 
			
		||||
  this.removeAllListeners("error");
 | 
			
		||||
  this.removeAllListeners("timeout");
 | 
			
		||||
  this.removeAllListeners("connect");
 | 
			
		||||
  this.removeAllListeners("end");
 | 
			
		||||
  this.removeAllListeners("parseError");
 | 
			
		||||
  this.removeAllListeners("message");
 | 
			
		||||
  this.removeAllListeners("poolReady");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										23
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/connection_utils.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										23
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/connection_utils.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
exports.setIntegerParameter = function(object, field, defaultValue) {
 | 
			
		||||
  if(object[field] == null) {
 | 
			
		||||
    object[field] = defaultValue;
 | 
			
		||||
  } else if(typeof object[field] !== "number" && object[field] !== parseInt(object[field], 10)) {
 | 
			
		||||
    throw "object field [" + field + "] must be a numeric integer value, attempted to set to [" + object[field] + "] type of [" + typeof object[field] + "]";
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.setBooleanParameter = function(object, field, defaultValue) {
 | 
			
		||||
  if(object[field] == null) {
 | 
			
		||||
    object[field] = defaultValue;
 | 
			
		||||
  } else if(typeof object[field] !== "boolean") {
 | 
			
		||||
    throw "object field [" + field + "] must be a boolean value, attempted to set to [" + object[field] + "] type of [" + typeof object[field] + "]";
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.setStringParameter = function(object, field, defaultValue) {
 | 
			
		||||
  if(object[field] == null) {
 | 
			
		||||
    object[field] = defaultValue;
 | 
			
		||||
  } else if(typeof object[field] !== "string") {
 | 
			
		||||
    throw "object field [" + field + "] must be a string value, attempted to set to [" + object[field] + "] type of [" + typeof object[field] + "]";
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										603
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/mongos.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										603
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/mongos.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,603 @@
 | 
			
		||||
var ReadPreference = require('./read_preference').ReadPreference
 | 
			
		||||
  , Base = require('./base').Base
 | 
			
		||||
  , ServerCapabilities = require('./server_capabilities').ServerCapabilities
 | 
			
		||||
  , Server = require('./server').Server
 | 
			
		||||
  , format = require('util').format
 | 
			
		||||
  , timers = require('timers')
 | 
			
		||||
  , utils = require('../utils')
 | 
			
		||||
  , inherits = require('util').inherits;
 | 
			
		||||
 | 
			
		||||
// Set processor, setImmediate if 0.10 otherwise nextTick
 | 
			
		||||
var processor = require('../utils').processor();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Mongos constructor provides a connection to a mongos proxy including failover to additional servers
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **socketOptions** {Object, default:null}, an object containing socket options to use (noDelay:(boolean), keepAlive:(number), connectTimeoutMS:(number), socketTimeoutMS:(number))
 | 
			
		||||
 *  - **ha** {Boolean, default:true}, turn on high availability, attempts to reconnect to down proxies
 | 
			
		||||
 *  - **haInterval** {Number, default:2000}, time between each replicaset status check.
 | 
			
		||||
 *
 | 
			
		||||
 * @class Represents a Mongos connection with failover to backup proxies
 | 
			
		||||
 * @param {Array} list of mongos server objects
 | 
			
		||||
 * @param {Object} [options] additional options for the mongos connection
 | 
			
		||||
 */
 | 
			
		||||
var Mongos = function Mongos(servers, options) {
 | 
			
		||||
  // Set up basic
 | 
			
		||||
  if(!(this instanceof Mongos))
 | 
			
		||||
    return new Mongos(servers, options);
 | 
			
		||||
 | 
			
		||||
  // Set up event emitter
 | 
			
		||||
  Base.call(this);
 | 
			
		||||
 | 
			
		||||
  // Throw error on wrong setup
 | 
			
		||||
  if(servers == null || !Array.isArray(servers) || servers.length == 0)
 | 
			
		||||
    throw new Error("At least one mongos proxy must be in the array");
 | 
			
		||||
 | 
			
		||||
  // Ensure we have at least an empty options object
 | 
			
		||||
  this.options = options == null ? {} : options;
 | 
			
		||||
  // Set default connection pool options
 | 
			
		||||
  this.socketOptions = this.options.socketOptions != null ? this.options.socketOptions : {};
 | 
			
		||||
  // Enabled ha
 | 
			
		||||
  this.haEnabled = this.options['ha'] == null ? true : this.options['ha'];
 | 
			
		||||
  this._haInProgress = false;
 | 
			
		||||
  // How often are we checking for new servers in the replicaset
 | 
			
		||||
  this.mongosStatusCheckInterval = this.options['haInterval'] == null ? 1000 : this.options['haInterval'];
 | 
			
		||||
  // Save all the server connections
 | 
			
		||||
  this.servers = servers;
 | 
			
		||||
  // Servers we need to attempt reconnect with
 | 
			
		||||
  this.downServers = {};
 | 
			
		||||
  // Servers that are up
 | 
			
		||||
  this.upServers = {};
 | 
			
		||||
  // Up servers by ping time
 | 
			
		||||
  this.upServersByUpTime = {};
 | 
			
		||||
  // Set poolsize or default
 | 
			
		||||
  this.poolSize = this.options.poolSize || 5;
 | 
			
		||||
  // Emit open setup
 | 
			
		||||
  this.emitOpen = this.options.emitOpen || true;
 | 
			
		||||
  // Just contains the current lowest ping time and server
 | 
			
		||||
  this.lowestPingTimeServer = null;
 | 
			
		||||
  this.lowestPingTime = 0;
 | 
			
		||||
  // Connection timeout
 | 
			
		||||
  this._connectTimeoutMS = this.socketOptions.connectTimeoutMS
 | 
			
		||||
    ? this.socketOptions.connectTimeoutMS
 | 
			
		||||
    : 1000;
 | 
			
		||||
 | 
			
		||||
  // Add options to servers
 | 
			
		||||
  for(var i = 0; i < this.servers.length; i++) {
 | 
			
		||||
    var server = this.servers[i];
 | 
			
		||||
    server._callBackStore = this._callBackStore;
 | 
			
		||||
    server.auto_reconnect = false;
 | 
			
		||||
    
 | 
			
		||||
    // Override pool size
 | 
			
		||||
    if(typeof this.poolSize == 'number') {
 | 
			
		||||
      server.poolSize = this.poolSize
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Default empty socket options object
 | 
			
		||||
    var socketOptions = {host: server.host, port: server.port};
 | 
			
		||||
    // If a socket option object exists clone it
 | 
			
		||||
    if(this.socketOptions != null) {
 | 
			
		||||
      var keys = Object.keys(this.socketOptions);
 | 
			
		||||
      for(var k = 0; k < keys.length;k++) socketOptions[keys[i]] = this.socketOptions[keys[i]];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Set socket options
 | 
			
		||||
    server.socketOptions = socketOptions;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Allow setting the socketTimeoutMS on all connections
 | 
			
		||||
  // to work around issues such as secondaries blocking due to compaction
 | 
			
		||||
  utils.setSocketTimeoutProperty(this, this.socketOptions);  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
inherits(Mongos, Base);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Mongos.prototype.isMongos = function() {
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Mongos.prototype.connect = function(db, options, callback) {
 | 
			
		||||
  if('function' === typeof options) callback = options, options = {};
 | 
			
		||||
  if(options == null) options = {};
 | 
			
		||||
  if(!('function' === typeof callback)) callback = null;
 | 
			
		||||
  var self = this;
 | 
			
		||||
 | 
			
		||||
  // Keep reference to parent
 | 
			
		||||
  this.db = db;
 | 
			
		||||
  // Set server state to connecting
 | 
			
		||||
  this._serverState = 'connecting';
 | 
			
		||||
  // Number of total servers that need to initialized (known servers)
 | 
			
		||||
  this._numberOfServersLeftToInitialize = this.servers.length;  
 | 
			
		||||
  // Connect handler
 | 
			
		||||
  var connectHandler = function(_server) {
 | 
			
		||||
    return function(err, result) {
 | 
			
		||||
      self._numberOfServersLeftToInitialize = self._numberOfServersLeftToInitialize - 1;
 | 
			
		||||
 | 
			
		||||
      // Add server capabilities
 | 
			
		||||
      if(_server.isMasterDoc) {
 | 
			
		||||
        // Set server capabilities
 | 
			
		||||
        _server.serverCapabilities = new ServerCapabilities(_server.isMasterDoc);
 | 
			
		||||
 | 
			
		||||
        // Set server capabilities on all the connections
 | 
			
		||||
        var connections = _server.allRawConnections();
 | 
			
		||||
        for(var i = 0; i < connections.length; i++) {
 | 
			
		||||
          connections[i].serverCapabilities = _server.serverCapabilities;
 | 
			
		||||
        }                
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Add the server to the list of servers that are up
 | 
			
		||||
      if(!err) {
 | 
			
		||||
        self.upServers[format("%s:%s", _server.host, _server.port)] = _server;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // We are done connecting
 | 
			
		||||
      if(self._numberOfServersLeftToInitialize == 0) {
 | 
			
		||||
        // If we have no valid mongos server instances error out
 | 
			
		||||
        if(Object.keys(self.upServers).length == 0) {
 | 
			
		||||
          // return self.emit("connectionError", new Error("No valid mongos instances found"));
 | 
			
		||||
          return callback(new Error("No valid mongos instances found"), null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Start ha function if it exists
 | 
			
		||||
        if(self.haEnabled) {
 | 
			
		||||
          // Setup the ha process
 | 
			
		||||
          if(self._replicasetTimeoutId != null) clearInterval(self._replicasetTimeoutId);
 | 
			
		||||
          self._replicasetTimeoutId = setInterval(self.mongosCheckFunction, self.mongosStatusCheckInterval);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Set the mongos to connected
 | 
			
		||||
        self._serverState = "connected";
 | 
			
		||||
 | 
			
		||||
        // Emit the open event
 | 
			
		||||
        if(self.emitOpen)
 | 
			
		||||
          self._emitAcrossAllDbInstances(self, null, "open", null, null, null);        
 | 
			
		||||
 | 
			
		||||
        self._emitAcrossAllDbInstances(self, null, "fullsetup", null, null, null);      
 | 
			
		||||
        // Callback
 | 
			
		||||
        callback(null, self.db);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // Error handler
 | 
			
		||||
  var errorOrCloseHandler = function(_server) {
 | 
			
		||||
    return function(err, result) {
 | 
			
		||||
      // Emit left event, signaling mongos left the ha
 | 
			
		||||
      self.emit('left', 'mongos', _server);
 | 
			
		||||
      // Execute all the callbacks with errors
 | 
			
		||||
      self.__executeAllCallbacksWithError(err);
 | 
			
		||||
      // Check if we have the server
 | 
			
		||||
      var found = false;
 | 
			
		||||
      
 | 
			
		||||
      // Get the server name
 | 
			
		||||
      var server_name = format("%s:%s", _server.host, _server.port);
 | 
			
		||||
      // Add the downed server
 | 
			
		||||
      self.downServers[server_name] = _server;
 | 
			
		||||
      // Remove the current server from the list
 | 
			
		||||
      delete self.upServers[server_name]; 
 | 
			
		||||
 | 
			
		||||
      // Emit close across all the attached db instances
 | 
			
		||||
      if(Object.keys(self.upServers).length == 0) {
 | 
			
		||||
        self._emitAcrossAllDbInstances(self, null, "close", new Error("mongos disconnected, no valid proxies contactable over tcp"), null, null);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Mongo function
 | 
			
		||||
  this.mongosCheckFunction = function() {
 | 
			
		||||
    // Set as not waiting for check event 
 | 
			
		||||
    self._haInProgress = true;
 | 
			
		||||
    
 | 
			
		||||
    // Servers down
 | 
			
		||||
    var numberOfServersLeft = Object.keys(self.downServers).length;
 | 
			
		||||
    
 | 
			
		||||
    // Check downed servers
 | 
			
		||||
    if(numberOfServersLeft > 0) {
 | 
			
		||||
      for(var name in self.downServers) {
 | 
			
		||||
        // Pop a downed server      
 | 
			
		||||
        var downServer = self.downServers[name];
 | 
			
		||||
        // Set up the connection options for a Mongos
 | 
			
		||||
        var options = {
 | 
			
		||||
          auto_reconnect: false,
 | 
			
		||||
          returnIsMasterResults: true,
 | 
			
		||||
          slaveOk: true,
 | 
			
		||||
          poolSize: self.poolSize,
 | 
			
		||||
          socketOptions: { 
 | 
			
		||||
            connectTimeoutMS: self._connectTimeoutMS,
 | 
			
		||||
            socketTimeoutMS: self._socketTimeoutMS
 | 
			
		||||
          }          
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Create a new server object
 | 
			
		||||
        var newServer = new Server(downServer.host, downServer.port, options);
 | 
			
		||||
        // Setup the connection function
 | 
			
		||||
        var connectFunction = function(_db, _server, _options, _callback)  {
 | 
			
		||||
          return function() {
 | 
			
		||||
            // Attempt to connect
 | 
			
		||||
            _server.connect(_db, _options, function(err, result) {
 | 
			
		||||
              numberOfServersLeft = numberOfServersLeft - 1;
 | 
			
		||||
 | 
			
		||||
              // Add server capabilities
 | 
			
		||||
              if(_server.isMasterDoc) {
 | 
			
		||||
                // Set server capabilities
 | 
			
		||||
                _server.serverCapabilities = new ServerCapabilities(_server.isMasterDoc);
 | 
			
		||||
 | 
			
		||||
                // Set server capabilities on all the connections
 | 
			
		||||
                var connections = _server.allRawConnections();
 | 
			
		||||
                for(var i = 0; i < connections.length; i++) {
 | 
			
		||||
                  connections[i].serverCapabilities = _server.serverCapabilities;
 | 
			
		||||
                }                
 | 
			
		||||
              }
 | 
			
		||||
 | 
			
		||||
              if(err) {
 | 
			
		||||
                return _callback(err, _server);
 | 
			
		||||
              } else {                
 | 
			
		||||
                // Set the new server settings
 | 
			
		||||
                _server._callBackStore = self._callBackStore;
 | 
			
		||||
 | 
			
		||||
                // Add server event handlers
 | 
			
		||||
                _server.on("close", errorOrCloseHandler(_server));
 | 
			
		||||
                _server.on("timeout", errorOrCloseHandler(_server));
 | 
			
		||||
                _server.on("error", errorOrCloseHandler(_server));
 | 
			
		||||
                
 | 
			
		||||
                // Get a read connection
 | 
			
		||||
                var _connection = _server.checkoutReader();
 | 
			
		||||
                // Get the start time
 | 
			
		||||
                var startTime = new Date().getTime();
 | 
			
		||||
                
 | 
			
		||||
                // Execute ping command to mark each server with the expected times
 | 
			
		||||
                self.db.command({ping:1}
 | 
			
		||||
                  , {failFast:true, connection:_connection}, function(err, result) {
 | 
			
		||||
                  // Get the start time
 | 
			
		||||
                  var endTime = new Date().getTime();
 | 
			
		||||
                  // Mark the server with the ping time
 | 
			
		||||
                  _server.runtimeStats['pingMs'] = endTime - startTime;
 | 
			
		||||
 | 
			
		||||
                  // If we have any buffered commands let's signal reconnect event
 | 
			
		||||
                  if(self._commandsStore.count() > 0) {
 | 
			
		||||
                    self.emit('reconnect');
 | 
			
		||||
                  }
 | 
			
		||||
 | 
			
		||||
                  // Execute any waiting reads
 | 
			
		||||
                  self._commandsStore.execute_writes();   
 | 
			
		||||
                  self._commandsStore.execute_queries();   
 | 
			
		||||
                  // Callback
 | 
			
		||||
                  return _callback(null, _server);
 | 
			
		||||
                });
 | 
			
		||||
              }
 | 
			
		||||
            });
 | 
			
		||||
          }
 | 
			
		||||
        } 
 | 
			
		||||
 | 
			
		||||
        // Attempt to connect to the database
 | 
			
		||||
        connectFunction(self.db, newServer, options, function(err, _server) {
 | 
			
		||||
          // If we have an error
 | 
			
		||||
          if(err) {
 | 
			
		||||
            self.downServers[format("%s:%s", _server.host, _server.port)] = _server;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          // Connection function
 | 
			
		||||
          var connectionFunction = function(_auth, _connection, _callback) {
 | 
			
		||||
            var pending = _auth.length();
 | 
			
		||||
 | 
			
		||||
            for(var j = 0; j < pending; j++) {
 | 
			
		||||
              // Get the auth object
 | 
			
		||||
              var _auth = _auth.get(j);
 | 
			
		||||
              // Unpack the parameter
 | 
			
		||||
              var username = _auth.username;
 | 
			
		||||
              var password = _auth.password;
 | 
			
		||||
              var options = { 
 | 
			
		||||
                  authMechanism: _auth.authMechanism
 | 
			
		||||
                , authSource: _auth.authdb
 | 
			
		||||
                , connection: _connection 
 | 
			
		||||
              };
 | 
			
		||||
 | 
			
		||||
              // If we have changed the service name
 | 
			
		||||
              if(_auth.gssapiServiceName) 
 | 
			
		||||
                options.gssapiServiceName = _auth.gssapiServiceName;
 | 
			
		||||
 | 
			
		||||
              // Hold any error
 | 
			
		||||
              var _error = null;
 | 
			
		||||
              // Authenticate against the credentials
 | 
			
		||||
              self.db.authenticate(username, password, options, function(err, result) {
 | 
			
		||||
                _error = err != null ? err : _error;
 | 
			
		||||
                // Adjust the pending authentication
 | 
			
		||||
                pending = pending - 1;
 | 
			
		||||
                // Finished up
 | 
			
		||||
                if(pending == 0) _callback(_error ? _error : null, _error ? false : true);
 | 
			
		||||
              });
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          // Run auths against the connections
 | 
			
		||||
          if(self.auth.length() > 0) {
 | 
			
		||||
            var connections = _server.allRawConnections();
 | 
			
		||||
            var pendingAuthConn = connections.length;
 | 
			
		||||
 | 
			
		||||
            // No connections we are done
 | 
			
		||||
            if(connections.length == 0) {
 | 
			
		||||
              // Set ha done
 | 
			
		||||
              if(numberOfServersLeft == 0) {
 | 
			
		||||
                self._haInProgress = false;
 | 
			
		||||
              }              
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Final error object
 | 
			
		||||
            var finalError = null;
 | 
			
		||||
            // Go over all the connections
 | 
			
		||||
            for(var j = 0; j < connections.length; j++) {
 | 
			
		||||
              
 | 
			
		||||
              // Execute against all the connections
 | 
			
		||||
              connectionFunction(self.auth, connections[j], function(err, result) {
 | 
			
		||||
                // Pending authentication
 | 
			
		||||
                pendingAuthConn = pendingAuthConn - 1 ;
 | 
			
		||||
 | 
			
		||||
                // Save error if any
 | 
			
		||||
                finalError = err ? err : finalError;
 | 
			
		||||
 | 
			
		||||
                // If we are done let's finish up
 | 
			
		||||
                if(pendingAuthConn == 0) {
 | 
			
		||||
                  // Set ha done
 | 
			
		||||
                  if(numberOfServersLeft == 0) {
 | 
			
		||||
                    self._haInProgress = false;
 | 
			
		||||
                  }
 | 
			
		||||
 | 
			
		||||
                  if(!err) {
 | 
			
		||||
                    add_server(self, _server);
 | 
			
		||||
                  }
 | 
			
		||||
 | 
			
		||||
                  // If we have any buffered commands let's signal reconnect event
 | 
			
		||||
                  if(self._commandsStore.count() > 0) {
 | 
			
		||||
                    self.emit('reconnect');
 | 
			
		||||
                  }
 | 
			
		||||
 | 
			
		||||
                  // Execute any waiting reads
 | 
			
		||||
                  self._commandsStore.execute_writes();   
 | 
			
		||||
                  self._commandsStore.execute_queries();                  
 | 
			
		||||
                }
 | 
			
		||||
              });
 | 
			
		||||
            }
 | 
			
		||||
          } else {
 | 
			
		||||
            if(!err) {
 | 
			
		||||
              add_server(self, _server);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Set ha done
 | 
			
		||||
            if(numberOfServersLeft == 0) {
 | 
			
		||||
              self._haInProgress = false;
 | 
			
		||||
 | 
			
		||||
              // If we have any buffered commands let's signal reconnect event
 | 
			
		||||
              if(self._commandsStore.count() > 0) {
 | 
			
		||||
                self.emit('reconnect');
 | 
			
		||||
              }
 | 
			
		||||
 | 
			
		||||
              // Execute any waiting reads
 | 
			
		||||
              self._commandsStore.execute_writes();   
 | 
			
		||||
              self._commandsStore.execute_queries();   
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        })();
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      self._haInProgress = false;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Connect all the server instances
 | 
			
		||||
  for(var i = 0; i < this.servers.length; i++) {
 | 
			
		||||
    // Get the connection
 | 
			
		||||
    var server = this.servers[i];
 | 
			
		||||
    server.mongosInstance = this;
 | 
			
		||||
    // Add server event handlers
 | 
			
		||||
    server.on("close", errorOrCloseHandler(server));
 | 
			
		||||
    server.on("timeout", errorOrCloseHandler(server));
 | 
			
		||||
    server.on("error", errorOrCloseHandler(server));
 | 
			
		||||
    
 | 
			
		||||
    // Configuration
 | 
			
		||||
    var options = {
 | 
			
		||||
      slaveOk: true,
 | 
			
		||||
      poolSize: this.poolSize || server.poolSize,
 | 
			
		||||
      socketOptions: { connectTimeoutMS: self._connectTimeoutMS },
 | 
			
		||||
      returnIsMasterResults: true
 | 
			
		||||
    }        
 | 
			
		||||
 | 
			
		||||
    // Connect the instance
 | 
			
		||||
    server.connect(self.db, options, connectHandler(server));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * Add a server to the list of up servers and sort them by ping time
 | 
			
		||||
 */
 | 
			
		||||
var add_server = function(self, _server) {
 | 
			
		||||
  // Emit a new server joined
 | 
			
		||||
  self.emit('joined', "mongos", null, _server);
 | 
			
		||||
  // Get the server url
 | 
			
		||||
  var server_key = format("%s:%s", _server.host, _server.port);
 | 
			
		||||
  // Push to list of valid server
 | 
			
		||||
  self.upServers[server_key] = _server;
 | 
			
		||||
  // Remove the server from the list of downed servers
 | 
			
		||||
  delete self.downServers[server_key];              
 | 
			
		||||
 | 
			
		||||
  // Sort the keys by ping time
 | 
			
		||||
  var keys = Object.keys(self.upServers);
 | 
			
		||||
  var _upServersSorted = {};
 | 
			
		||||
  var _upServers = []
 | 
			
		||||
  
 | 
			
		||||
  // Get all the servers
 | 
			
		||||
  for(var name in self.upServers) {
 | 
			
		||||
    _upServers.push(self.upServers[name]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Sort all the server
 | 
			
		||||
  _upServers.sort(function(a, b) {
 | 
			
		||||
    return a.runtimeStats['pingMs'] > b.runtimeStats['pingMs'];
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // Rebuild the upServer
 | 
			
		||||
  for(var i = 0; i < _upServers.length; i++) {
 | 
			
		||||
    _upServersSorted[format("%s:%s", _upServers[i].host, _upServers[i].port)] = _upServers[i];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Set the up servers
 | 
			
		||||
  self.upServers = _upServersSorted;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * Just return the currently picked active connection
 | 
			
		||||
 */
 | 
			
		||||
Mongos.prototype.allServerInstances = function() {
 | 
			
		||||
  return this.servers;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Mongos.prototype.setSocketOptions = function(options) {
 | 
			
		||||
  var servers = this.allServerInstances();
 | 
			
		||||
  for(var i = 0; i < servers.length; i++) {
 | 
			
		||||
    servers[i].setSocketOptions(options);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Always ourselves
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Mongos.prototype.setReadPreference = function() {}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Mongos.prototype.allRawConnections = function() {
 | 
			
		||||
  // Neeed to build a complete list of all raw connections, start with master server
 | 
			
		||||
  var allConnections = [];
 | 
			
		||||
  // Get all connected connections
 | 
			
		||||
  for(var name in this.upServers) {
 | 
			
		||||
    allConnections = allConnections.concat(this.upServers[name].allRawConnections());
 | 
			
		||||
  }
 | 
			
		||||
  // Return all the conections
 | 
			
		||||
  return allConnections;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Mongos.prototype.isConnected = function() {
 | 
			
		||||
  return Object.keys(this.upServers).length > 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Mongos.prototype.isAutoReconnect = function() {
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Mongos.prototype.canWrite = Mongos.prototype.isConnected;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Mongos.prototype.canRead = Mongos.prototype.isConnected;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Mongos.prototype.isDestroyed = function() {
 | 
			
		||||
  return this._serverState == 'destroyed';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Mongos.prototype.checkoutWriter = function() {
 | 
			
		||||
  // Checkout a writer
 | 
			
		||||
  var keys = Object.keys(this.upServers);
 | 
			
		||||
  if(keys.length == 0) return null;
 | 
			
		||||
  return this.upServers[keys[0]].checkoutWriter();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Mongos.prototype.checkoutReader = function(read) {
 | 
			
		||||
  // If read is set to null default to primary
 | 
			
		||||
  read = read || 'primary'
 | 
			
		||||
  // If we have a read preference object unpack it
 | 
			
		||||
  if(read != null && typeof read == 'object' && read['_type'] == 'ReadPreference') {
 | 
			
		||||
    // Validate if the object is using a valid mode
 | 
			
		||||
    if(!read.isValid()) throw new Error("Illegal readPreference mode specified, " + JSON.stringify(read));
 | 
			
		||||
  } else if(!ReadPreference.isValid(read)) {
 | 
			
		||||
    throw new Error("Illegal readPreference mode specified, " + JSON.stringify(read));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Checkout a writer
 | 
			
		||||
  var keys = Object.keys(this.upServers);
 | 
			
		||||
  if(keys.length == 0) return null;
 | 
			
		||||
  return this.upServers[keys[0]].checkoutWriter();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Mongos.prototype.close = function(callback) {
 | 
			
		||||
  var self = this;
 | 
			
		||||
  // Set server status as disconnected
 | 
			
		||||
  this._serverState = 'destroyed';
 | 
			
		||||
  // Number of connections to close
 | 
			
		||||
  var numberOfConnectionsToClose = self.servers.length;
 | 
			
		||||
  // If we have a ha process running kill it
 | 
			
		||||
  if(self._replicasetTimeoutId != null) clearInterval(self._replicasetTimeoutId);
 | 
			
		||||
  self._replicasetTimeoutId = null;
 | 
			
		||||
  
 | 
			
		||||
  // Emit close event
 | 
			
		||||
  processor(function() {
 | 
			
		||||
    self._emitAcrossAllDbInstances(self, null, "close", null, null, true)    
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // Flush out any remaining call handlers
 | 
			
		||||
  self._flushAllCallHandlers(utils.toError("Connection Closed By Application"));
 | 
			
		||||
 | 
			
		||||
  // No up servers just return
 | 
			
		||||
  if(Object.keys(this.upServers) == 0) {
 | 
			
		||||
    return callback(null);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Close all the up servers
 | 
			
		||||
  for(var name in this.upServers) {
 | 
			
		||||
    this.upServers[name].close(function(err, result) {
 | 
			
		||||
      numberOfConnectionsToClose = numberOfConnectionsToClose - 1;
 | 
			
		||||
 | 
			
		||||
      // Callback if we have one defined
 | 
			
		||||
      if(numberOfConnectionsToClose == 0 && typeof callback == 'function') {
 | 
			
		||||
        callback(null);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * Return the used state
 | 
			
		||||
 */
 | 
			
		||||
Mongos.prototype._isUsed = function() {
 | 
			
		||||
  return this._used;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.Mongos = Mongos;
 | 
			
		||||
							
								
								
									
										67
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/read_preference.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										67
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/read_preference.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,67 @@
 | 
			
		||||
/**
 | 
			
		||||
 * A class representation of the Read Preference.
 | 
			
		||||
 *
 | 
			
		||||
 * Read Preferences
 | 
			
		||||
 *  - **ReadPreference.PRIMARY**, Read from primary only. All operations produce an error (throw an exception where applicable) if primary is unavailable. Cannot be combined with tags (This is the default.).
 | 
			
		||||
 *  - **ReadPreference.PRIMARY_PREFERRED**, Read from primary if available, otherwise a secondary.
 | 
			
		||||
 *  - **ReadPreference.SECONDARY**, Read from secondary if available, otherwise error.
 | 
			
		||||
 *  - **ReadPreference.SECONDARY_PREFERRED**, Read from a secondary if available, otherwise read from the primary.
 | 
			
		||||
 *  - **ReadPreference.NEAREST**, All modes read from among the nearest candidates, but unlike other modes, NEAREST will include both the primary and all secondaries in the random selection.
 | 
			
		||||
 *
 | 
			
		||||
 * @class Represents a Read Preference.
 | 
			
		||||
 * @param {String} the read preference type
 | 
			
		||||
 * @param {Object} tags
 | 
			
		||||
 * @return {ReadPreference}
 | 
			
		||||
 */
 | 
			
		||||
var ReadPreference = function(mode, tags) {
 | 
			
		||||
  if(!(this instanceof ReadPreference))
 | 
			
		||||
    return new ReadPreference(mode, tags);
 | 
			
		||||
  this._type = 'ReadPreference';
 | 
			
		||||
  this.mode = mode;
 | 
			
		||||
  this.tags = tags;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
ReadPreference.isValid = function(_mode) {
 | 
			
		||||
  return (_mode == ReadPreference.PRIMARY || _mode == ReadPreference.PRIMARY_PREFERRED
 | 
			
		||||
    || _mode == ReadPreference.SECONDARY || _mode == ReadPreference.SECONDARY_PREFERRED
 | 
			
		||||
    || _mode == ReadPreference.NEAREST
 | 
			
		||||
    || _mode == true || _mode == false || _mode == null);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
ReadPreference.prototype.isValid = function(mode) {
 | 
			
		||||
  var _mode = typeof mode == 'string' ? mode : this.mode;
 | 
			
		||||
  return ReadPreference.isValid(_mode);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
ReadPreference.prototype.toObject = function() {
 | 
			
		||||
  var object = {mode:this.mode};
 | 
			
		||||
 | 
			
		||||
  if(this.tags != null) {
 | 
			
		||||
    object['tags'] = this.tags;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return object;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
ReadPreference.PRIMARY = 'primary';
 | 
			
		||||
ReadPreference.PRIMARY_PREFERRED = 'primaryPreferred';
 | 
			
		||||
ReadPreference.SECONDARY = 'secondary';
 | 
			
		||||
ReadPreference.SECONDARY_PREFERRED = 'secondaryPreferred';
 | 
			
		||||
ReadPreference.NEAREST = 'nearest'
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
exports.ReadPreference  = ReadPreference;
 | 
			
		||||
							
								
								
									
										473
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/repl_set/ha.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										473
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/repl_set/ha.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,473 @@
 | 
			
		||||
var DbCommand = require('../../commands/db_command').DbCommand
 | 
			
		||||
  , ServerCapabilities = require('../server_capabilities').ServerCapabilities
 | 
			
		||||
  , format = require('util').format;
 | 
			
		||||
 | 
			
		||||
var HighAvailabilityProcess = function(replset, options) {  
 | 
			
		||||
  this.replset = replset;
 | 
			
		||||
  this.options = options;
 | 
			
		||||
  this.server = null;
 | 
			
		||||
  this.state = HighAvailabilityProcess.INIT;
 | 
			
		||||
  this.selectedIndex = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
HighAvailabilityProcess.INIT = 'init';
 | 
			
		||||
HighAvailabilityProcess.RUNNING = 'running';
 | 
			
		||||
HighAvailabilityProcess.STOPPED = 'stopped';
 | 
			
		||||
 | 
			
		||||
HighAvailabilityProcess.prototype.start = function() {  
 | 
			
		||||
  var self = this;
 | 
			
		||||
  if(this.replset._state 
 | 
			
		||||
    && Object.keys(this.replset._state.addresses).length == 0) {
 | 
			
		||||
    if(this.server) this.server.close();
 | 
			
		||||
    this.state = HighAvailabilityProcess.STOPPED;
 | 
			
		||||
    return;      
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(this.server) this.server.close();
 | 
			
		||||
  // Start the running
 | 
			
		||||
  this._haProcessInProcess = false;
 | 
			
		||||
  this.state = HighAvailabilityProcess.RUNNING;
 | 
			
		||||
  
 | 
			
		||||
  // Get all possible reader servers
 | 
			
		||||
  var candidate_servers = this.replset._state.getAllReadServers();
 | 
			
		||||
  if(candidate_servers.length == 0) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Select a candidate server for the connection
 | 
			
		||||
  var server = candidate_servers[this.selectedIndex % candidate_servers.length];
 | 
			
		||||
  this.selectedIndex = this.selectedIndex + 1;
 | 
			
		||||
  
 | 
			
		||||
  // Unpack connection options
 | 
			
		||||
  var connectTimeoutMS = self.options.connectTimeoutMS || 10000;
 | 
			
		||||
  var socketTimeoutMS = self.options.socketTimeoutMS || 30000;
 | 
			
		||||
 | 
			
		||||
  // Just ensure we don't have a full cycle dependency
 | 
			
		||||
  var Db = require('../../db').Db
 | 
			
		||||
  var Server = require('../server').Server;
 | 
			
		||||
 | 
			
		||||
  // Set up a new server instance
 | 
			
		||||
  var newServer = new Server(server.host, server.port, {
 | 
			
		||||
      auto_reconnect: false
 | 
			
		||||
    , returnIsMasterResults: true
 | 
			
		||||
    , poolSize: 1
 | 
			
		||||
    , socketOptions: { 
 | 
			
		||||
        connectTimeoutMS: connectTimeoutMS,
 | 
			
		||||
        socketTimeoutMS: socketTimeoutMS,
 | 
			
		||||
        keepAlive: 100
 | 
			
		||||
      }
 | 
			
		||||
    , ssl: self.replset.options.ssl
 | 
			
		||||
    , sslValidate: self.replset.options.sslValidate
 | 
			
		||||
    , sslCA: self.replset.options.sslCA
 | 
			
		||||
    , sslCert: self.replset.options.sslCert
 | 
			
		||||
    , sslKey: self.replset.options.sslKey
 | 
			
		||||
    , sslPass: self.replset.options.sslPass
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // Create new dummy db for app
 | 
			
		||||
  self.db = new Db('local', newServer, {w:1});
 | 
			
		||||
 | 
			
		||||
  // Set up the event listeners
 | 
			
		||||
  newServer.once("error", _handle(this, newServer));
 | 
			
		||||
  newServer.once("close", _handle(this, newServer));
 | 
			
		||||
  newServer.once("timeout", _handle(this, newServer));
 | 
			
		||||
  newServer.name = format("%s:%s", server.host, server.port);
 | 
			
		||||
 | 
			
		||||
  // Let's attempt a connection over here
 | 
			
		||||
  newServer.connect(self.db, function(err, result, _server) {
 | 
			
		||||
    // Emit ha_connect
 | 
			
		||||
    self.replset.emit("ha_connect", err, result, _server);
 | 
			
		||||
 | 
			
		||||
    if(self.state == HighAvailabilityProcess.STOPPED) {
 | 
			
		||||
      _server.close();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Ensure server capabilities object is on all connections
 | 
			
		||||
    if(_server.isMasterDoc) {
 | 
			
		||||
      // Set server capabilities
 | 
			
		||||
      _server.serverCapabilities = new ServerCapabilities(_server.isMasterDoc);
 | 
			
		||||
 | 
			
		||||
      // Set server capabilities on all the connections
 | 
			
		||||
      var connections = _server.allRawConnections();
 | 
			
		||||
      for(var i = 0; i < connections.length; i++) {
 | 
			
		||||
        connections[i].serverCapabilities = _server.serverCapabilities;
 | 
			
		||||
      }      
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(err) {
 | 
			
		||||
      // Close the server
 | 
			
		||||
      _server.close();
 | 
			
		||||
      // Check if we can even do HA (is there anything running)
 | 
			
		||||
      if(Object.keys(self.replset._state.addresses).length == 0) {
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      // Let's boot the ha timeout settings
 | 
			
		||||
      setTimeout(function() {
 | 
			
		||||
        self.start();
 | 
			
		||||
      }, self.options.haInterval);
 | 
			
		||||
    } else {
 | 
			
		||||
      self.server = _server;
 | 
			
		||||
      // Let's boot the ha timeout settings
 | 
			
		||||
      setTimeout(_timeoutHandle(self), self.options.haInterval);
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
HighAvailabilityProcess.prototype.stop = function() {
 | 
			
		||||
  this.state = HighAvailabilityProcess.STOPPED;
 | 
			
		||||
  if(this.server) this.server.close();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _timeoutHandle = function(self) {
 | 
			
		||||
  return function() {
 | 
			
		||||
    if(self.state == HighAvailabilityProcess.STOPPED) {
 | 
			
		||||
      // Stop all server instances
 | 
			
		||||
      for(var name in self.replset._state.addresses) {
 | 
			
		||||
        self.replset._state.addresses[name].close();
 | 
			
		||||
        delete self.replset._state.addresses[name];
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Finished pinging
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If the server is connected
 | 
			
		||||
    if(self.server.isConnected() && !self._haProcessInProcess) {
 | 
			
		||||
      // Start HA process
 | 
			
		||||
      self._haProcessInProcess = true;
 | 
			
		||||
      // Execute is master command
 | 
			
		||||
      self.db._executeQueryCommand(DbCommand.createIsMasterCommand(self.db), 
 | 
			
		||||
          {failFast:true, connection: self.server.checkoutReader()}
 | 
			
		||||
        , function(err, res) {
 | 
			
		||||
          // Emit ha event
 | 
			
		||||
          self.replset.emit("ha_ismaster", err, res);
 | 
			
		||||
 | 
			
		||||
          // If we have an error close
 | 
			
		||||
          if(err) {
 | 
			
		||||
            self.server.close();
 | 
			
		||||
            // Re-run loop
 | 
			
		||||
            return setTimeout(_timeoutHandle(self), self.options.haInterval);
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          // Master document
 | 
			
		||||
          var master = res.documents[0];
 | 
			
		||||
          var hosts = master.hosts || [];
 | 
			
		||||
          var reconnect_servers = [];
 | 
			
		||||
          var state = self.replset._state;
 | 
			
		||||
 | 
			
		||||
          // We are in recovery mode, let's remove the current server
 | 
			
		||||
          if(!master.ismaster 
 | 
			
		||||
            && !master.secondary
 | 
			
		||||
            && state.addresses[master.me]) {
 | 
			
		||||
              self.server.close();
 | 
			
		||||
              state.addresses[master.me].close();
 | 
			
		||||
              delete state.secondaries[master.me];
 | 
			
		||||
              // Re-run loop
 | 
			
		||||
              return setTimeout(_timeoutHandle(self), self.options.haInterval);
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          // We have a new master different front he current one
 | 
			
		||||
          if((master.primary && state.master == null)
 | 
			
		||||
            || (master.primary && state.master.name != master.primary)) {
 | 
			
		||||
 | 
			
		||||
            // Locate the primary and set it
 | 
			
		||||
            if(state.addresses[master.primary]) {
 | 
			
		||||
              if(state.master) state.master.close();
 | 
			
		||||
              delete state.secondaries[master.primary];
 | 
			
		||||
              state.master = state.addresses[master.primary];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Emit joined event due to primary change
 | 
			
		||||
            self.replset.emit('joined', "primary", master, state.master);
 | 
			
		||||
            
 | 
			
		||||
            // Set up the changes
 | 
			
		||||
            if(state.master != null && state.master.isMasterDoc != null) {
 | 
			
		||||
              state.master.isMasterDoc.ismaster = true;
 | 
			
		||||
              state.master.isMasterDoc.secondary = false;                
 | 
			
		||||
            } else if(state.master != null) {
 | 
			
		||||
              state.master.isMasterDoc = master;
 | 
			
		||||
              state.master.isMasterDoc.ismaster = true;
 | 
			
		||||
              state.master.isMasterDoc.secondary = false;                
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // If we have any buffered commands let's signal reconnect event
 | 
			
		||||
            if(self.replset._commandsStore.count() > 0) {
 | 
			
		||||
              self.replset.emit('reconnect');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Execute any waiting commands (queries or writes)
 | 
			
		||||
            self.replset._commandsStore.execute_queries();
 | 
			
		||||
            self.replset._commandsStore.execute_writes();   
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          // For all the hosts let's check that we have connections
 | 
			
		||||
          for(var i = 0; i < hosts.length; i++) {
 | 
			
		||||
            var host = hosts[i];
 | 
			
		||||
            
 | 
			
		||||
            // Check if we need to reconnect to a server
 | 
			
		||||
            if(state.addresses[host] == null) {
 | 
			
		||||
              reconnect_servers.push(host);
 | 
			
		||||
            } else if(state.addresses[host] && !state.addresses[host].isConnected()) {
 | 
			
		||||
              state.addresses[host].close();
 | 
			
		||||
              delete state.secondaries[host];
 | 
			
		||||
              reconnect_servers.push(host);              
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          // Let's reconnect to any server needed
 | 
			
		||||
          if(reconnect_servers.length > 0) {
 | 
			
		||||
            _reconnect_servers(self, reconnect_servers);  
 | 
			
		||||
          } else {
 | 
			
		||||
            self._haProcessInProcess = false
 | 
			
		||||
            return setTimeout(_timeoutHandle(self), self.options.haInterval);
 | 
			
		||||
          }
 | 
			
		||||
      });
 | 
			
		||||
    } else if(!self.server.isConnected()) {
 | 
			
		||||
      setTimeout(function() {
 | 
			
		||||
        return self.start();
 | 
			
		||||
      }, self.options.haInterval);
 | 
			
		||||
    } else {
 | 
			
		||||
      setTimeout(_timeoutHandle(self), self.options.haInterval);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _reconnect_servers = function(self, reconnect_servers) {
 | 
			
		||||
  if(reconnect_servers.length == 0) {
 | 
			
		||||
    self._haProcessInProcess = false    
 | 
			
		||||
    return setTimeout(_timeoutHandle(self), self.options.haInterval);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Unpack connection options
 | 
			
		||||
  var connectTimeoutMS = self.options.connectTimeoutMS || 10000;
 | 
			
		||||
  var socketTimeoutMS = self.options.socketTimeoutMS || 0;
 | 
			
		||||
 | 
			
		||||
  // Server class
 | 
			
		||||
  var Db = require('../../db').Db
 | 
			
		||||
  var Server = require('../server').Server;
 | 
			
		||||
  // Get the host
 | 
			
		||||
  var host = reconnect_servers.shift();
 | 
			
		||||
  // Split it up
 | 
			
		||||
  var _host = host.split(":")[0];
 | 
			
		||||
  var _port = parseInt(host.split(":")[1], 10);
 | 
			
		||||
 | 
			
		||||
  // Set up a new server instance
 | 
			
		||||
  var newServer = new Server(_host, _port, {
 | 
			
		||||
      auto_reconnect: false
 | 
			
		||||
    , returnIsMasterResults: true
 | 
			
		||||
    , poolSize: self.options.poolSize
 | 
			
		||||
    , socketOptions: { 
 | 
			
		||||
        connectTimeoutMS: connectTimeoutMS,
 | 
			
		||||
        socketTimeoutMS: socketTimeoutMS
 | 
			
		||||
      }
 | 
			
		||||
    , ssl: self.replset.options.ssl
 | 
			
		||||
    , sslValidate: self.replset.options.sslValidate
 | 
			
		||||
    , sslCA: self.replset.options.sslCA
 | 
			
		||||
    , sslCert: self.replset.options.sslCert
 | 
			
		||||
    , sslKey: self.replset.options.sslKey
 | 
			
		||||
    , sslPass: self.replset.options.sslPass
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // Create new dummy db for app
 | 
			
		||||
  var db = new Db('local', newServer, {w:1});
 | 
			
		||||
  var state = self.replset._state;
 | 
			
		||||
 | 
			
		||||
  // Set up the event listeners
 | 
			
		||||
  newServer.once("error", _repl_set_handler("error", self.replset, newServer));
 | 
			
		||||
  newServer.once("close", _repl_set_handler("close", self.replset, newServer));
 | 
			
		||||
  newServer.once("timeout", _repl_set_handler("timeout", self.replset, newServer));
 | 
			
		||||
 | 
			
		||||
  // Set shared state
 | 
			
		||||
  newServer.name = host;
 | 
			
		||||
  newServer._callBackStore = self.replset._callBackStore;
 | 
			
		||||
  newServer.replicasetInstance = self.replset;
 | 
			
		||||
  newServer.enableRecordQueryStats(self.replset.recordQueryStats);
 | 
			
		||||
 | 
			
		||||
  // Let's attempt a connection over here
 | 
			
		||||
  newServer.connect(db, function(err, result, _server) {
 | 
			
		||||
    // Emit ha_connect
 | 
			
		||||
    self.replset.emit("ha_connect", err, result, _server);
 | 
			
		||||
 | 
			
		||||
    if(self.state == HighAvailabilityProcess.STOPPED) {
 | 
			
		||||
      _server.close();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Ensure server capabilities object is on all connections
 | 
			
		||||
    if(_server.isMasterDoc) {
 | 
			
		||||
      // Set server capabilities
 | 
			
		||||
      _server.serverCapabilities = new ServerCapabilities(_server.isMasterDoc);
 | 
			
		||||
 | 
			
		||||
      // Set server capabilities on all the connections
 | 
			
		||||
      var connections = _server.allRawConnections();
 | 
			
		||||
      for(var i = 0; i < connections.length; i++) {
 | 
			
		||||
        connections[i].serverCapabilities = _server.serverCapabilities;
 | 
			
		||||
      }      
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If we connected let's check what kind of server we have
 | 
			
		||||
    if(!err) {
 | 
			
		||||
      _apply_auths(self, db, _server, function(err, result) {
 | 
			
		||||
        if(err) {
 | 
			
		||||
          _server.close();
 | 
			
		||||
          // Process the next server
 | 
			
		||||
          return setTimeout(function() {
 | 
			
		||||
            _reconnect_servers(self, reconnect_servers);  
 | 
			
		||||
          }, self.options.haInterval);                      
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        var doc = _server.isMasterDoc;    
 | 
			
		||||
        // Fire error on any unknown callbacks for this server
 | 
			
		||||
        self.replset.__executeAllServerSpecificErrorCallbacks(_server.socketOptions.host, _server.socketOptions.port, err);    
 | 
			
		||||
 | 
			
		||||
        if(doc.ismaster) {
 | 
			
		||||
          // Emit primary added
 | 
			
		||||
          self.replset.emit('joined', "primary", doc, _server);
 | 
			
		||||
 | 
			
		||||
          // If it was a secondary remove it
 | 
			
		||||
          if(state.secondaries[doc.me]) {
 | 
			
		||||
            delete state.secondaries[doc.me];
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          // Override any server in list of addresses
 | 
			
		||||
          state.addresses[doc.me] = _server;
 | 
			
		||||
          // Set server as master
 | 
			
		||||
          state.master = _server;
 | 
			
		||||
 | 
			
		||||
          // If we have any buffered commands let's signal reconnect event
 | 
			
		||||
          if(self.replset._commandsStore.count() > 0) {
 | 
			
		||||
            self.replset.emit('reconnect');
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          // Execute any waiting writes
 | 
			
		||||
          self.replset._commandsStore.execute_writes();   
 | 
			
		||||
        } else if(doc.secondary) {
 | 
			
		||||
          // Emit secondary added
 | 
			
		||||
          self.replset.emit('joined', "secondary", doc, _server);
 | 
			
		||||
          // Add the secondary to the state
 | 
			
		||||
          state.secondaries[doc.me] = _server;
 | 
			
		||||
          // Override any server in list of addresses
 | 
			
		||||
          state.addresses[doc.me] = _server;
 | 
			
		||||
 | 
			
		||||
          // If we have any buffered commands let's signal reconnect event
 | 
			
		||||
          if(self.replset._commandsStore.count() > 0) {
 | 
			
		||||
            self.replset.emit('reconnect');
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          // Execute any waiting reads
 | 
			
		||||
          self.replset._commandsStore.execute_queries();   
 | 
			
		||||
        } else {
 | 
			
		||||
          _server.close();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Set any tags on the instance server
 | 
			
		||||
        _server.name = doc.me;
 | 
			
		||||
        _server.tags = doc.tags;
 | 
			
		||||
        // Process the next server
 | 
			
		||||
        setTimeout(function() {
 | 
			
		||||
          _reconnect_servers(self, reconnect_servers);  
 | 
			
		||||
        }, self.options.haInterval);            
 | 
			
		||||
      });
 | 
			
		||||
    } else {
 | 
			
		||||
      _server.close();
 | 
			
		||||
      self.replset.__executeAllServerSpecificErrorCallbacks(_server.socketOptions.host, _server.socketOptions.port, err);    
 | 
			
		||||
 | 
			
		||||
      setTimeout(function() {
 | 
			
		||||
        _reconnect_servers(self, reconnect_servers);  
 | 
			
		||||
      }, self.options.haInterval);            
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _apply_auths = function(self, _db, _server, _callback) {
 | 
			
		||||
  if(self.replset.auth.length() == 0) return _callback(null);
 | 
			
		||||
  // Apply any authentication needed
 | 
			
		||||
  if(self.replset.auth.length() > 0) {
 | 
			
		||||
    var pending = self.replset.auth.length();
 | 
			
		||||
    var connections = _server.allRawConnections();
 | 
			
		||||
    var pendingAuthConn = connections.length;
 | 
			
		||||
    // Connection function
 | 
			
		||||
    var connectionFunction = function(auth, _connection, __callback) {
 | 
			
		||||
      var pending = auth.length();
 | 
			
		||||
 | 
			
		||||
      for(var j = 0; j < pending; j++) {
 | 
			
		||||
        // Get the auth object
 | 
			
		||||
        var _auth = auth.get(j);
 | 
			
		||||
        // Unpack the parameter
 | 
			
		||||
        var username = _auth.username;
 | 
			
		||||
        var password = _auth.password;
 | 
			
		||||
        var options = { 
 | 
			
		||||
            authMechanism: _auth.authMechanism            
 | 
			
		||||
          , authSource: _auth.authdb
 | 
			
		||||
          , connection: _connection 
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // If we have changed the service name
 | 
			
		||||
        if(_auth.gssapiServiceName) 
 | 
			
		||||
          options.gssapiServiceName = _auth.gssapiServiceName;
 | 
			
		||||
        
 | 
			
		||||
        // Hold any error
 | 
			
		||||
        var _error = null;
 | 
			
		||||
        
 | 
			
		||||
        // Authenticate against the credentials
 | 
			
		||||
        _db.authenticate(username, password, options, function(err, result) {
 | 
			
		||||
          _error = err != null ? err : _error;
 | 
			
		||||
          // Adjust the pending authentication
 | 
			
		||||
          pending = pending - 1;
 | 
			
		||||
          // Finished up
 | 
			
		||||
          if(pending == 0) __callback(_error ? _error : null, _error ? false : true);
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Final error object
 | 
			
		||||
    var finalError = null;
 | 
			
		||||
    // Iterate over all the connections
 | 
			
		||||
    for(var i = 0; i < connections.length; i++) {
 | 
			
		||||
      connectionFunction(self.replset.auth, connections[i], function(err, result) {
 | 
			
		||||
        // Pending authentication
 | 
			
		||||
        pendingAuthConn = pendingAuthConn - 1 ;
 | 
			
		||||
 | 
			
		||||
        // Save error if any
 | 
			
		||||
        finalError = err ? err : finalError;
 | 
			
		||||
 | 
			
		||||
        // If we are done let's finish up
 | 
			
		||||
        if(pendingAuthConn == 0) {
 | 
			
		||||
          _callback(null);
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _handle = function(self, server) {
 | 
			
		||||
  return function(err) {
 | 
			
		||||
    server.close();    
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _repl_set_handler = function(event, self, server) {
 | 
			
		||||
  var ReplSet = require('./repl_set').ReplSet;
 | 
			
		||||
 | 
			
		||||
  return function(err, doc) {
 | 
			
		||||
    server.close();
 | 
			
		||||
 | 
			
		||||
    // The event happened to a primary
 | 
			
		||||
    // Remove it from play
 | 
			
		||||
    if(self._state.isPrimary(server)) {
 | 
			
		||||
      self._state.master == null;
 | 
			
		||||
      self._serverState = ReplSet.REPLSET_READ_ONLY;
 | 
			
		||||
    } else if(self._state.isSecondary(server)) {
 | 
			
		||||
      delete self._state.secondaries[server.name];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Unpack variables
 | 
			
		||||
    var host = server.socketOptions.host;
 | 
			
		||||
    var port = server.socketOptions.port;
 | 
			
		||||
 | 
			
		||||
    // Fire error on any unknown callbacks
 | 
			
		||||
    self.__executeAllServerSpecificErrorCallbacks(host, port, err);    
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.HighAvailabilityProcess = HighAvailabilityProcess;
 | 
			
		||||
							
								
								
									
										126
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/repl_set/options.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										126
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/repl_set/options.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,126 @@
 | 
			
		||||
var PingStrategy = require('./strategies/ping_strategy').PingStrategy
 | 
			
		||||
  , StatisticsStrategy = require('./strategies/statistics_strategy').StatisticsStrategy
 | 
			
		||||
  , ReadPreference = require('../read_preference').ReadPreference;
 | 
			
		||||
 | 
			
		||||
var Options = function(options) {
 | 
			
		||||
  options = options || {};
 | 
			
		||||
  this._options = options;
 | 
			
		||||
  this.ha = options.ha || true;
 | 
			
		||||
  this.haInterval = options.haInterval || 2000;
 | 
			
		||||
  this.reconnectWait = options.reconnectWait || 1000;
 | 
			
		||||
  this.retries = options.retries || 30;
 | 
			
		||||
  this.rs_name = options.rs_name;
 | 
			
		||||
  this.socketOptions = options.socketOptions || {};
 | 
			
		||||
  this.readPreference = options.readPreference;
 | 
			
		||||
  this.readSecondary = options.read_secondary;
 | 
			
		||||
  this.poolSize = options.poolSize == null ? 5 : options.poolSize;
 | 
			
		||||
  this.strategy = options.strategy || 'ping';
 | 
			
		||||
  this.secondaryAcceptableLatencyMS = options.secondaryAcceptableLatencyMS || 15;
 | 
			
		||||
  this.connectArbiter = options.connectArbiter || false;
 | 
			
		||||
  this.connectWithNoPrimary = options.connectWithNoPrimary || false;
 | 
			
		||||
  this.logger = options.logger;
 | 
			
		||||
  this.ssl = options.ssl || false;
 | 
			
		||||
  this.sslValidate = options.sslValidate || false;
 | 
			
		||||
  this.sslCA = options.sslCA;
 | 
			
		||||
  this.sslCert = options.sslCert;
 | 
			
		||||
  this.sslKey = options.sslKey;
 | 
			
		||||
  this.sslPass = options.sslPass;
 | 
			
		||||
  this.emitOpen = options.emitOpen || true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Options.prototype.init = function() {
 | 
			
		||||
  if(this.sslValidate && (!Array.isArray(this.sslCA) || this.sslCA.length == 0)) {
 | 
			
		||||
    throw new Error("The driver expects an Array of CA certificates in the sslCA parameter when enabling sslValidate");
 | 
			
		||||
  }  
 | 
			
		||||
 | 
			
		||||
  // Make sure strategy is one of the two allowed
 | 
			
		||||
  if(this.strategy != null && (this.strategy != 'ping' && this.strategy != 'statistical' && this.strategy != 'none')) 
 | 
			
		||||
      throw new Error("Only ping or statistical strategies allowed");    
 | 
			
		||||
  
 | 
			
		||||
  if(this.strategy == null) this.strategy = 'ping';
 | 
			
		||||
  
 | 
			
		||||
  // Set logger if strategy exists
 | 
			
		||||
  if(this.strategyInstance) this.strategyInstance.logger = this.logger;
 | 
			
		||||
 | 
			
		||||
  // Unpack read Preference
 | 
			
		||||
  var readPreference = this.readPreference;
 | 
			
		||||
  // Validate correctness of Read preferences
 | 
			
		||||
  if(readPreference != null) {
 | 
			
		||||
    if(readPreference != ReadPreference.PRIMARY && readPreference != ReadPreference.PRIMARY_PREFERRED
 | 
			
		||||
      && readPreference != ReadPreference.SECONDARY && readPreference != ReadPreference.SECONDARY_PREFERRED
 | 
			
		||||
      && readPreference != ReadPreference.NEAREST && typeof readPreference != 'object' && readPreference['_type'] != 'ReadPreference') {
 | 
			
		||||
      throw new Error("Illegal readPreference mode specified, " + JSON.stringify(readPreference));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.readPreference = readPreference;
 | 
			
		||||
  } else {
 | 
			
		||||
    this.readPreference = null;
 | 
			
		||||
  } 
 | 
			
		||||
 | 
			
		||||
     // Ensure read_secondary is set correctly
 | 
			
		||||
  if(this.readSecondary != null)
 | 
			
		||||
    this.readSecondary = this.readPreference == ReadPreference.PRIMARY 
 | 
			
		||||
        || this.readPreference == false  
 | 
			
		||||
        || this.readPreference == null ? false : true;
 | 
			
		||||
 | 
			
		||||
  // Ensure correct slave set
 | 
			
		||||
  if(this.readSecondary) this.slaveOk = true;
 | 
			
		||||
 | 
			
		||||
  // Set up logger if any set
 | 
			
		||||
  this.logger = this.logger != null
 | 
			
		||||
    && (typeof this.logger.debug == 'function')
 | 
			
		||||
    && (typeof this.logger.error == 'function')
 | 
			
		||||
    && (typeof this.logger.debug == 'function')
 | 
			
		||||
      ? this.logger : {error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}};  
 | 
			
		||||
 | 
			
		||||
  // Connection timeout
 | 
			
		||||
  this.connectTimeoutMS = typeof this.socketOptions.connectTimeoutMS == 'number'
 | 
			
		||||
    ? this.socketOptions.connectTimeoutMS
 | 
			
		||||
    : 1000;
 | 
			
		||||
 | 
			
		||||
  // Socket connection timeout
 | 
			
		||||
  this.socketTimeoutMS = typeof this.socketOptions.socketTimeoutMS == 'number'
 | 
			
		||||
    ? this.socketOptions.socketTimeoutMS
 | 
			
		||||
    : 30000;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Options.prototype.decorateAndClean = function(servers, callBackStore) {
 | 
			
		||||
  var self = this;
 | 
			
		||||
 | 
			
		||||
  // var de duplicate list
 | 
			
		||||
  var uniqueServers = {};
 | 
			
		||||
  // De-duplicate any servers in the seed list
 | 
			
		||||
  for(var i = 0; i < servers.length; i++) {
 | 
			
		||||
    var server = servers[i];
 | 
			
		||||
    // If server does not exist set it
 | 
			
		||||
    if(uniqueServers[server.host + ":" + server.port] == null) {
 | 
			
		||||
      uniqueServers[server.host + ":" + server.port] = server;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Let's set the deduplicated list of servers
 | 
			
		||||
  var finalServers = [];
 | 
			
		||||
  // Add the servers
 | 
			
		||||
  for(var key in uniqueServers) {
 | 
			
		||||
    finalServers.push(uniqueServers[key]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  finalServers.forEach(function(server) {
 | 
			
		||||
    // Ensure no server has reconnect on
 | 
			
		||||
    server.options.auto_reconnect = false;
 | 
			
		||||
    // Set up ssl options
 | 
			
		||||
    server.ssl = self.ssl;
 | 
			
		||||
    server.sslValidate = self.sslValidate;
 | 
			
		||||
    server.sslCA = self.sslCA;
 | 
			
		||||
    server.sslCert = self.sslCert;
 | 
			
		||||
    server.sslKey = self.sslKey;
 | 
			
		||||
    server.sslPass = self.sslPass;
 | 
			
		||||
    server.poolSize = self.poolSize;
 | 
			
		||||
    // Set callback store
 | 
			
		||||
    server._callBackStore = callBackStore;
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  return finalServers;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.Options = Options;
 | 
			
		||||
							
								
								
									
										839
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/repl_set/repl_set.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										839
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/repl_set/repl_set.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,839 @@
 | 
			
		||||
var ReadPreference = require('../read_preference').ReadPreference
 | 
			
		||||
  , DbCommand = require('../../commands/db_command').DbCommand
 | 
			
		||||
  , inherits = require('util').inherits
 | 
			
		||||
  , format = require('util').format
 | 
			
		||||
  , timers = require('timers')
 | 
			
		||||
  , Server = require('../server').Server
 | 
			
		||||
  , utils = require('../../utils')
 | 
			
		||||
  , PingStrategy = require('./strategies/ping_strategy').PingStrategy
 | 
			
		||||
  , StatisticsStrategy = require('./strategies/statistics_strategy').StatisticsStrategy
 | 
			
		||||
  , Options = require('./options').Options
 | 
			
		||||
  , ServerCapabilities = require('../server_capabilities').ServerCapabilities
 | 
			
		||||
  , ReplSetState = require('./repl_set_state').ReplSetState
 | 
			
		||||
  , HighAvailabilityProcess = require('./ha').HighAvailabilityProcess
 | 
			
		||||
  , Base = require('../base').Base;
 | 
			
		||||
 | 
			
		||||
var STATE_STARTING_PHASE_1 = 0;
 | 
			
		||||
var STATE_PRIMARY = 1;
 | 
			
		||||
var STATE_SECONDARY = 2;
 | 
			
		||||
var STATE_RECOVERING = 3;
 | 
			
		||||
var STATE_FATAL_ERROR = 4;
 | 
			
		||||
var STATE_STARTING_PHASE_2 = 5;
 | 
			
		||||
var STATE_UNKNOWN = 6;
 | 
			
		||||
var STATE_ARBITER = 7;
 | 
			
		||||
var STATE_DOWN = 8;
 | 
			
		||||
var STATE_ROLLBACK = 9;
 | 
			
		||||
 | 
			
		||||
// Set processor, setImmediate if 0.10 otherwise nextTick
 | 
			
		||||
var processor = require('../../utils').processor();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ReplSet constructor provides replicaset functionality
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **ha** {Boolean, default:true}, turn on high availability.
 | 
			
		||||
 *  - **haInterval** {Number, default:2000}, time between each replicaset status check.
 | 
			
		||||
 *  - **reconnectWait** {Number, default:1000}, time to wait in miliseconds before attempting reconnect.
 | 
			
		||||
 *  - **retries** {Number, default:30}, number of times to attempt a replicaset reconnect.
 | 
			
		||||
 *  - **rs_name** {String}, the name of the replicaset to connect to.
 | 
			
		||||
 *  - **socketOptions** {Object, default:null}, an object containing socket options to use (noDelay:(boolean), keepAlive:(number), connectTimeoutMS:(number), socketTimeoutMS:(number))
 | 
			
		||||
 *  - **strategy** {String, default:'ping'}, selection strategy for reads choose between (ping, statistical and none, default is ping)
 | 
			
		||||
 *  - **secondaryAcceptableLatencyMS** {Number, default:15}, sets the range of servers to pick when using NEAREST (lowest ping ms + the latency fence, ex: range of 1 to (1 + 15) ms)
 | 
			
		||||
 *  - **connectWithNoPrimary** {Boolean, default:false}, sets if the driver should connect even if no primary is available
 | 
			
		||||
 *  - **connectArbiter** {Boolean, default:false}, sets if the driver should connect to arbiters or not.
 | 
			
		||||
 *  - **logger** {Object, default:null}, an object representing a logger that you want to use, needs to support functions debug, log, error **({error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}})**.
 | 
			
		||||
 *  - **poolSize** {Number, default:5}, number of connections in the connection pool for each server instance, set to 5 as default for legacy reasons.
 | 
			
		||||
 *  - **ssl** {Boolean, default:false}, use ssl connection (needs to have a mongod server with ssl support)
 | 
			
		||||
 *  - **sslValidate** {Boolean, default:false}, validate mongod server certificate against ca (needs to have a mongod server with ssl support, 2.4 or higher)
 | 
			
		||||
 *  - **sslCA** {Array, default:null}, Array of valid certificates either as Buffers or Strings (needs to have a mongod server with ssl support, 2.4 or higher)
 | 
			
		||||
 *  - **sslCert** {Buffer/String, default:null}, String or buffer containing the certificate we wish to present (needs to have a mongod server with ssl support, 2.4 or higher)
 | 
			
		||||
 *  - **sslKey** {Buffer/String, default:null}, String or buffer containing the certificate private key we wish to present (needs to have a mongod server with ssl support, 2.4 or higher)
 | 
			
		||||
 *  - **sslPass** {Buffer/String, default:null}, String or buffer containing the certificate password (needs to have a mongod server with ssl support, 2.4 or higher)
 | 
			
		||||
 *
 | 
			
		||||
 * @class Represents a 
 | 
			
		||||
 Replicaset Configuration
 | 
			
		||||
 * @param {Array} list of server objects participating in the replicaset.
 | 
			
		||||
 * @param {Object} [options] additional options for the replicaset connection.
 | 
			
		||||
 */
 | 
			
		||||
var ReplSet = exports.ReplSet = function(servers, options) {
 | 
			
		||||
  // Set up basic
 | 
			
		||||
  if(!(this instanceof ReplSet))
 | 
			
		||||
    return new ReplSet(servers, options);
 | 
			
		||||
 | 
			
		||||
  // Set up event emitter
 | 
			
		||||
  Base.call(this);
 | 
			
		||||
 | 
			
		||||
  // Ensure we have a list of servers
 | 
			
		||||
  if(!Array.isArray(servers)) throw Error("The parameter must be an array of servers and contain at least one server");
 | 
			
		||||
  // Ensure no Mongos's
 | 
			
		||||
  for(var i = 0; i < servers.length; i++) {
 | 
			
		||||
    if(!(servers[i] instanceof Server)) throw new Error("list of servers must be of type Server");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Save the options
 | 
			
		||||
  this.options = new Options(options);
 | 
			
		||||
  // Ensure basic validation of options
 | 
			
		||||
  this.options.init();
 | 
			
		||||
 | 
			
		||||
  // Server state
 | 
			
		||||
  this._serverState = ReplSet.REPLSET_DISCONNECTED;
 | 
			
		||||
  // Add high availability process
 | 
			
		||||
  this._haProcess = new HighAvailabilityProcess(this, this.options);
 | 
			
		||||
 | 
			
		||||
  // Let's iterate over all the provided server objects and decorate them
 | 
			
		||||
  this.servers = this.options.decorateAndClean(servers, this._callBackStore);
 | 
			
		||||
  // Throw error if no seed servers
 | 
			
		||||
  if(this.servers.length == 0) throw new Error("No valid seed servers in the array");
 | 
			
		||||
 | 
			
		||||
  // Let's set up our strategy object for picking secondaries
 | 
			
		||||
  if(this.options.strategy == 'ping') {
 | 
			
		||||
    // Create a new instance
 | 
			
		||||
    this.strategyInstance = new PingStrategy(this, this.options.secondaryAcceptableLatencyMS);
 | 
			
		||||
  } else if(this.options.strategy == 'statistical') {
 | 
			
		||||
    // Set strategy as statistical
 | 
			
		||||
    this.strategyInstance = new StatisticsStrategy(this);
 | 
			
		||||
    // Add enable query information
 | 
			
		||||
    this.enableRecordQueryStats(true);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.emitOpen = this.options.emitOpen || true;
 | 
			
		||||
  // Set up a clean state
 | 
			
		||||
  this._state = new ReplSetState(this);
 | 
			
		||||
  // Current round robin selected server
 | 
			
		||||
  this._currentServerChoice = 0;
 | 
			
		||||
  // Ensure up the server callbacks
 | 
			
		||||
  for(var i = 0; i < this.servers.length; i++) {
 | 
			
		||||
    this.servers[i]._callBackStore = this._callBackStore;
 | 
			
		||||
    this.servers[i].name = format("%s:%s", this.servers[i].host, this.servers[i].port)
 | 
			
		||||
    this.servers[i].replicasetInstance = this;
 | 
			
		||||
    this.servers[i].options.auto_reconnect = false;
 | 
			
		||||
    this.servers[i].poolSize = this.options.poolSize;
 | 
			
		||||
    this.servers[i].inheritReplSetOptionsFrom(this);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Allow setting the socketTimeoutMS on all connections
 | 
			
		||||
  // to work around issues such as secondaries blocking due to compaction
 | 
			
		||||
  utils.setSocketTimeoutProperty(this, this.options.socketOptions);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
inherits(ReplSet, Base);
 | 
			
		||||
 | 
			
		||||
// Replicaset states
 | 
			
		||||
ReplSet.REPLSET_CONNECTING = 'connecting';
 | 
			
		||||
ReplSet.REPLSET_DISCONNECTED = 'disconnected';
 | 
			
		||||
ReplSet.REPLSET_CONNECTED = 'connected';
 | 
			
		||||
ReplSet.REPLSET_RECONNECTING = 'reconnecting';
 | 
			
		||||
ReplSet.REPLSET_DESTROYED = 'destroyed';
 | 
			
		||||
ReplSet.REPLSET_READ_ONLY = 'readonly';
 | 
			
		||||
 | 
			
		||||
ReplSet.prototype.isAutoReconnect = function() {
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ReplSet.prototype.canWrite = function() {
 | 
			
		||||
  return this._state.master && this._state.master.isConnected();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ReplSet.prototype.canRead = function(read) {
 | 
			
		||||
  if((read == ReadPreference.PRIMARY 
 | 
			
		||||
      || (typeof read == 'object' && read.mode == ReadPreference.PRIMARY)
 | 
			
		||||
      || read == null || read == false) && (this._state.master == null || !this._state.master.isConnected())) return false;
 | 
			
		||||
  return Object.keys(this._state.secondaries).length > 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
ReplSet.prototype.enableRecordQueryStats = function(enable) {
 | 
			
		||||
  // Set the global enable record query stats
 | 
			
		||||
  this.recordQueryStats = enable;
 | 
			
		||||
 | 
			
		||||
  // Enable all the servers
 | 
			
		||||
  for(var i = 0; i < this.servers.length; i++) {
 | 
			
		||||
    this.servers[i].enableRecordQueryStats(enable);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
ReplSet.prototype.setSocketOptions = function(options) {
 | 
			
		||||
  var servers = this.allServerInstances();
 | 
			
		||||
  
 | 
			
		||||
  if(typeof options.socketTimeoutMS == 'number') {
 | 
			
		||||
    this.options.socketOptions.socketTimeoutMS = options.socketTimeoutMS;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(typeof options.connectTimeoutMS == 'number')
 | 
			
		||||
    this.options.socketOptions.connectTimeoutMS = options.connectTimeoutMS;
 | 
			
		||||
 | 
			
		||||
  for(var i = 0; i < servers.length; i++) {
 | 
			
		||||
    servers[i].setSocketOptions(options);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
ReplSet.prototype.setReadPreference = function(preference) {
 | 
			
		||||
  this.options.readPreference = preference;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ReplSet.prototype.connect = function(parent, options, callback) {
 | 
			
		||||
  if(this._serverState != ReplSet.REPLSET_DISCONNECTED) 
 | 
			
		||||
    return callback(new Error("in process of connection"));
 | 
			
		||||
 | 
			
		||||
  // If no callback throw
 | 
			
		||||
  if(!(typeof callback == 'function')) 
 | 
			
		||||
    throw new Error("cannot call ReplSet.prototype.connect with no callback function");
 | 
			
		||||
 | 
			
		||||
  var self = this;
 | 
			
		||||
  // Save db reference
 | 
			
		||||
  this.options.db = parent;
 | 
			
		||||
  // Set replicaset as connecting
 | 
			
		||||
  this._serverState = ReplSet.REPLSET_CONNECTING
 | 
			
		||||
  // Copy all the servers to our list of seeds
 | 
			
		||||
  var candidateServers = this.servers.slice(0);
 | 
			
		||||
  // Pop the first server
 | 
			
		||||
  var server = candidateServers.pop();
 | 
			
		||||
  server.name = format("%s:%s", server.host, server.port);
 | 
			
		||||
  // Set up the options
 | 
			
		||||
  var opts = {
 | 
			
		||||
    returnIsMasterResults: true,
 | 
			
		||||
    eventReceiver: server
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Register some event listeners
 | 
			
		||||
  this.once("fullsetup", function(err, db, replset) {
 | 
			
		||||
    // Set state to connected
 | 
			
		||||
    self._serverState = ReplSet.REPLSET_CONNECTED;
 | 
			
		||||
    // Stop any process running
 | 
			
		||||
    if(self._haProcess) self._haProcess.stop();
 | 
			
		||||
    // Start the HA process
 | 
			
		||||
    self._haProcess.start();
 | 
			
		||||
 | 
			
		||||
    // Emit fullsetup
 | 
			
		||||
    processor(function() {
 | 
			
		||||
      if(self.emitOpen)
 | 
			
		||||
        self._emitAcrossAllDbInstances(self, null, "open", null, null, null);        
 | 
			
		||||
 | 
			
		||||
      self._emitAcrossAllDbInstances(self, null, "fullsetup", null, null, null);        
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // If we have a strategy defined start it
 | 
			
		||||
    if(self.strategyInstance) {
 | 
			
		||||
      self.strategyInstance.start();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Finishing up the call
 | 
			
		||||
    callback(err, db, replset);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // Errors
 | 
			
		||||
  this.once("connectionError", function(err, result) {
 | 
			
		||||
    callback(err, result);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // Attempt to connect to the server
 | 
			
		||||
  server.connect(this.options.db, opts, _connectHandler(this, candidateServers, server));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ReplSet.prototype.close = function(callback) {  
 | 
			
		||||
  var self = this;
 | 
			
		||||
  // Set as destroyed
 | 
			
		||||
  this._serverState = ReplSet.REPLSET_DESTROYED;
 | 
			
		||||
  // Stop the ha
 | 
			
		||||
  this._haProcess.stop();
 | 
			
		||||
  
 | 
			
		||||
  // If we have a strategy stop it
 | 
			
		||||
  if(this.strategyInstance) {
 | 
			
		||||
    this.strategyInstance.stop();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Kill all servers available
 | 
			
		||||
  for(var name in this._state.addresses) {
 | 
			
		||||
    this._state.addresses[name].close();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Clean out the state
 | 
			
		||||
  this._state = new ReplSetState(this); 
 | 
			
		||||
  
 | 
			
		||||
  // Emit close event
 | 
			
		||||
  processor(function() {
 | 
			
		||||
    self._emitAcrossAllDbInstances(self, null, "close", null, null, true)    
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // Flush out any remaining call handlers
 | 
			
		||||
  self._flushAllCallHandlers(utils.toError("Connection Closed By Application"));
 | 
			
		||||
 | 
			
		||||
  // Callback
 | 
			
		||||
  if(typeof callback == 'function') 
 | 
			
		||||
    return callback(null, null);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Creates a new server for the `replset` based on `host`.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {String} host - host:port pair (localhost:27017)
 | 
			
		||||
 * @param {ReplSet} replset - the ReplSet instance
 | 
			
		||||
 * @return {Server}
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
var createServer = function(self, host, options) {
 | 
			
		||||
  // copy existing socket options to new server
 | 
			
		||||
  var socketOptions = {}
 | 
			
		||||
  if(options.socketOptions) {
 | 
			
		||||
    var keys = Object.keys(options.socketOptions);
 | 
			
		||||
    for(var k = 0; k < keys.length; k++) {
 | 
			
		||||
      socketOptions[keys[k]] = options.socketOptions[keys[k]];
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var parts = host.split(/:/);
 | 
			
		||||
  if(1 === parts.length) {
 | 
			
		||||
    parts[1] = Connection.DEFAULT_PORT;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  socketOptions.host = parts[0];
 | 
			
		||||
  socketOptions.port = parseInt(parts[1], 10);
 | 
			
		||||
 | 
			
		||||
  var serverOptions = {
 | 
			
		||||
    readPreference: options.readPreference,
 | 
			
		||||
    socketOptions: socketOptions,
 | 
			
		||||
    poolSize: options.poolSize,
 | 
			
		||||
    logger: options.logger,
 | 
			
		||||
    auto_reconnect: false,
 | 
			
		||||
    ssl: options.ssl,
 | 
			
		||||
    sslValidate: options.sslValidate,
 | 
			
		||||
    sslCA: options.sslCA,
 | 
			
		||||
    sslCert: options.sslCert,
 | 
			
		||||
    sslKey: options.sslKey,
 | 
			
		||||
    sslPass: options.sslPass
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var server = new Server(socketOptions.host, socketOptions.port, serverOptions);
 | 
			
		||||
  // Set up shared state
 | 
			
		||||
  server._callBackStore = self._callBackStore;
 | 
			
		||||
  server.replicasetInstance = self;
 | 
			
		||||
  server.enableRecordQueryStats(self.recordQueryStats);
 | 
			
		||||
  // Set up event handlers
 | 
			
		||||
  server.on("close", _handler("close", self, server));
 | 
			
		||||
  server.on("error", _handler("error", self, server));
 | 
			
		||||
  server.on("timeout", _handler("timeout", self, server));
 | 
			
		||||
  return server;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _handler = function(event, self, server) {
 | 
			
		||||
  return function(err, doc) {
 | 
			
		||||
    // The event happened to a primary
 | 
			
		||||
    // Remove it from play
 | 
			
		||||
    if(self._state.isPrimary(server)) {    
 | 
			
		||||
      // Emit that the primary left the replicaset
 | 
			
		||||
      self.emit('left', 'primary', server);
 | 
			
		||||
      // Get the current master
 | 
			
		||||
      var current_master = self._state.master;
 | 
			
		||||
      self._state.master = null;
 | 
			
		||||
      self._serverState = ReplSet.REPLSET_READ_ONLY;
 | 
			
		||||
    
 | 
			
		||||
      if(current_master != null) {
 | 
			
		||||
        // Unpack variables
 | 
			
		||||
        var host = current_master.socketOptions.host;
 | 
			
		||||
        var port = current_master.socketOptions.port;
 | 
			
		||||
 | 
			
		||||
        // Fire error on any unknown callbacks
 | 
			
		||||
        self.__executeAllServerSpecificErrorCallbacks(host, port, err);        
 | 
			
		||||
      }
 | 
			
		||||
    } else if(self._state.isSecondary(server)) {
 | 
			
		||||
      // Emit that a secondary left the replicaset
 | 
			
		||||
      self.emit('left', 'secondary', server);
 | 
			
		||||
      // Delete from the list
 | 
			
		||||
      delete self._state.secondaries[server.name];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If there is no more connections left and the setting is not destroyed
 | 
			
		||||
    // set to disconnected
 | 
			
		||||
    if(Object.keys(self._state.addresses).length == 0 
 | 
			
		||||
      && self._serverState != ReplSet.REPLSET_DESTROYED) {
 | 
			
		||||
        self._serverState = ReplSet.REPLSET_DISCONNECTED;
 | 
			
		||||
 | 
			
		||||
        // Emit close across all the attached db instances
 | 
			
		||||
        self._dbStore.emit("close", new Error("replicaset disconnected, no valid servers contactable over tcp"), null, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Unpack variables
 | 
			
		||||
    var host = server.socketOptions.host;
 | 
			
		||||
    var port = server.socketOptions.port;
 | 
			
		||||
 | 
			
		||||
    // Fire error on any unknown callbacks
 | 
			
		||||
    self.__executeAllServerSpecificErrorCallbacks(host, port, err);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var locateNewServers = function(self, state, candidateServers, ismaster) {
 | 
			
		||||
  // Retrieve the host
 | 
			
		||||
  var hosts = ismaster.hosts;
 | 
			
		||||
  // In candidate servers
 | 
			
		||||
  var inCandidateServers = function(name, candidateServers) {
 | 
			
		||||
    for(var i = 0; i < candidateServers.length; i++) {
 | 
			
		||||
      if(candidateServers[i].name == name) return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // New servers
 | 
			
		||||
  var newServers = [];
 | 
			
		||||
  if(Array.isArray(hosts)) {
 | 
			
		||||
    // Let's go over all the hosts
 | 
			
		||||
    for(var i = 0; i < hosts.length; i++) {
 | 
			
		||||
      if(!state.contains(hosts[i]) 
 | 
			
		||||
        && !inCandidateServers(hosts[i], candidateServers)) {
 | 
			
		||||
          newServers.push(createServer(self, hosts[i], self.options));
 | 
			
		||||
      }
 | 
			
		||||
    }    
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Return list of possible new servers
 | 
			
		||||
  return newServers;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _connectHandler = function(self, candidateServers, instanceServer) {
 | 
			
		||||
  return function(err, doc) {
 | 
			
		||||
    // If we have an error add to the list
 | 
			
		||||
    if(err) {
 | 
			
		||||
      self._state.errors[instanceServer.name] = instanceServer;
 | 
			
		||||
    } else {
 | 
			
		||||
      delete self._state.errors[instanceServer.name];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(!err) {      
 | 
			
		||||
      var ismaster = doc.documents[0]
 | 
			
		||||
 | 
			
		||||
      // Error the server if 
 | 
			
		||||
      if(!ismaster.ismaster
 | 
			
		||||
        && !ismaster.secondary) {
 | 
			
		||||
        self._state.errors[instanceServer.name] = instanceServer;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Set server capabilities
 | 
			
		||||
      instanceServer.serverCapabilities = new ServerCapabilities(ismaster);
 | 
			
		||||
 | 
			
		||||
      // Set server capabilities on all the connections
 | 
			
		||||
      var connections = instanceServer.allRawConnections();
 | 
			
		||||
      for(var i = 0; i < connections.length; i++) {
 | 
			
		||||
        connections[i].serverCapabilities = instanceServer.serverCapabilities;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // No error let's analyse the ismaster command
 | 
			
		||||
    if(!err && self._state.errors[instanceServer.name] == null) {
 | 
			
		||||
      var ismaster = doc.documents[0]
 | 
			
		||||
 | 
			
		||||
      // If no replicaset name exists set the current one
 | 
			
		||||
      if(self.options.rs_name == null) {
 | 
			
		||||
        self.options.rs_name = ismaster.setName;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // If we have a member that is not part of the set let's finish up
 | 
			
		||||
      if(typeof ismaster.setName == 'string' && ismaster.setName != self.options.rs_name) {
 | 
			
		||||
        return self.emit("connectionError", new Error("Replicaset name " + ismaster.setName + " does not match specified name " + self.options.rs_name));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Add the error handlers
 | 
			
		||||
      instanceServer.on("close", _handler("close", self, instanceServer));
 | 
			
		||||
      instanceServer.on("error", _handler("error", self, instanceServer));
 | 
			
		||||
      instanceServer.on("timeout", _handler("timeout", self, instanceServer));
 | 
			
		||||
      
 | 
			
		||||
      // Set any tags on the instance server
 | 
			
		||||
      instanceServer.name = ismaster.me;
 | 
			
		||||
      instanceServer.tags = ismaster.tags;
 | 
			
		||||
 | 
			
		||||
      // Add the server to the list
 | 
			
		||||
      self._state.addServer(instanceServer, ismaster);
 | 
			
		||||
 | 
			
		||||
      // Check if we have more servers to add (only check when done with initial set)
 | 
			
		||||
      if(candidateServers.length == 0) {
 | 
			
		||||
        // Get additional new servers that are not currently in set
 | 
			
		||||
        var new_servers = locateNewServers(self, self._state, candidateServers, ismaster);
 | 
			
		||||
 | 
			
		||||
        // Locate any new servers that have not errored out yet
 | 
			
		||||
        for(var i = 0; i < new_servers.length; i++) {
 | 
			
		||||
          if(self._state.errors[new_servers[i].name] == null) {
 | 
			
		||||
            candidateServers.push(new_servers[i])            
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If the candidate server list is empty and no valid servers
 | 
			
		||||
    if(candidateServers.length == 0 &&
 | 
			
		||||
      !self._state.hasValidServers()) {
 | 
			
		||||
        return self.emit("connectionError", new Error("No valid replicaset instance servers found"));
 | 
			
		||||
    } else if(candidateServers.length == 0) {      
 | 
			
		||||
      if(!self.options.connectWithNoPrimary && (self._state.master == null || !self._state.master.isConnected())) {
 | 
			
		||||
        return self.emit("connectionError", new Error("No primary found in set"));
 | 
			
		||||
      }
 | 
			
		||||
      return self.emit("fullsetup", null, self.options.db, self);
 | 
			
		||||
    }
 | 
			
		||||
        
 | 
			
		||||
    // Let's connect the next server    
 | 
			
		||||
    var nextServer = candidateServers.pop();
 | 
			
		||||
  
 | 
			
		||||
    // Set up the options
 | 
			
		||||
    var opts = {
 | 
			
		||||
      returnIsMasterResults: true,
 | 
			
		||||
      eventReceiver: nextServer
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Attempt to connect to the server
 | 
			
		||||
    nextServer.connect(self.options.db, opts, _connectHandler(self, candidateServers, nextServer));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ReplSet.prototype.isDestroyed = function() {
 | 
			
		||||
  return this._serverState == ReplSet.REPLSET_DESTROYED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ReplSet.prototype.isConnected = function(read) {
 | 
			
		||||
  var isConnected = false;  
 | 
			
		||||
 | 
			
		||||
  if(read == null || read == ReadPreference.PRIMARY || read == false)
 | 
			
		||||
    isConnected = this._state.master != null && this._state.master.isConnected();
 | 
			
		||||
 | 
			
		||||
  if((read == ReadPreference.PRIMARY_PREFERRED || read == ReadPreference.SECONDARY_PREFERRED || read == ReadPreference.NEAREST)
 | 
			
		||||
    && ((this._state.master != null && this._state.master.isConnected())
 | 
			
		||||
    || (this._state && this._state.secondaries && Object.keys(this._state.secondaries).length > 0))) {
 | 
			
		||||
      isConnected = true;
 | 
			
		||||
  } else if(read == ReadPreference.SECONDARY) {
 | 
			
		||||
    isConnected = this._state && this._state.secondaries && Object.keys(this._state.secondaries).length > 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // No valid connection return false
 | 
			
		||||
  return isConnected;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ReplSet.prototype.isMongos = function() {
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ReplSet.prototype.checkoutWriter = function() {
 | 
			
		||||
  if(this._state.master) return this._state.master.checkoutWriter();
 | 
			
		||||
  return new Error("no writer connection available");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ReplSet.prototype.processIsMaster = function(_server, _ismaster) {
 | 
			
		||||
  // Server in recovery mode, remove it from available servers
 | 
			
		||||
  if(!_ismaster.ismaster && !_ismaster.secondary) {
 | 
			
		||||
    // Locate the actual server
 | 
			
		||||
    var server = this._state.addresses[_server.name];
 | 
			
		||||
    // Close the server, simulating the closing of the connection
 | 
			
		||||
    // to get right removal semantics
 | 
			
		||||
    if(server) server.close();
 | 
			
		||||
    // Execute any callback errors
 | 
			
		||||
    _handler(null, this, server)(new Error("server is in recovery mode"));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ReplSet.prototype.allRawConnections = function() {
 | 
			
		||||
  var connections = [];
 | 
			
		||||
 | 
			
		||||
  for(var name in this._state.addresses) {
 | 
			
		||||
    connections = connections.concat(this._state.addresses[name].allRawConnections());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return connections;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
ReplSet.prototype.allServerInstances = function() {
 | 
			
		||||
  var self = this;
 | 
			
		||||
  // If no state yet return empty
 | 
			
		||||
  if(!self._state) return [];
 | 
			
		||||
  // Close all the servers (concatenate entire list of servers first for ease)
 | 
			
		||||
  var allServers = self._state.master != null ? [self._state.master] : [];
 | 
			
		||||
 | 
			
		||||
  // Secondary keys
 | 
			
		||||
  var keys = Object.keys(self._state.secondaries);
 | 
			
		||||
  // Add all secondaries
 | 
			
		||||
  for(var i = 0; i < keys.length; i++) {
 | 
			
		||||
    allServers.push(self._state.secondaries[keys[i]]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Return complete list of all servers
 | 
			
		||||
  return allServers;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
ReplSet.prototype.checkoutReader = function(readPreference, tags) {
 | 
			
		||||
  var connection = null;
 | 
			
		||||
 | 
			
		||||
  // If we have a read preference object unpack it
 | 
			
		||||
  if(typeof readPreference == 'object' && readPreference['_type'] == 'ReadPreference') {
 | 
			
		||||
    // Validate if the object is using a valid mode
 | 
			
		||||
    if(!readPreference.isValid()) throw new Error("Illegal readPreference mode specified, " + JSON.stringify(readPreference.mode));
 | 
			
		||||
    // Set the tag
 | 
			
		||||
    tags = readPreference.tags;
 | 
			
		||||
    readPreference = readPreference.mode;
 | 
			
		||||
  } else if(typeof readPreference == 'object' && readPreference['_type'] != 'ReadPreference') {
 | 
			
		||||
    return new Error("read preferences must be either a string or an instance of ReadPreference");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Set up our read Preference, allowing us to override the readPreference
 | 
			
		||||
  var finalReadPreference = readPreference != null ? readPreference : this.options.readPreference;
 | 
			
		||||
 | 
			
		||||
  // Ensure we unpack a reference
 | 
			
		||||
  if(finalReadPreference != null && typeof finalReadPreference == 'object' && finalReadPreference['_type'] == 'ReadPreference') {
 | 
			
		||||
    // Validate if the object is using a valid mode
 | 
			
		||||
    if(!finalReadPreference.isValid()) throw new Error("Illegal readPreference mode specified, " + JSON.stringify(finalReadPreference.mode));
 | 
			
		||||
    // Set the tag
 | 
			
		||||
    tags = finalReadPreference.tags;
 | 
			
		||||
    readPreference = finalReadPreference.mode;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Finalize the read preference setup
 | 
			
		||||
  finalReadPreference = finalReadPreference == true ? ReadPreference.SECONDARY_PREFERRED : finalReadPreference;
 | 
			
		||||
  finalReadPreference = finalReadPreference == null ? ReadPreference.PRIMARY : finalReadPreference;
 | 
			
		||||
 | 
			
		||||
  // If we are reading from a primary
 | 
			
		||||
  if(finalReadPreference == 'primary') {
 | 
			
		||||
    // If we provide a tags set send an error
 | 
			
		||||
    if(typeof tags == 'object' && tags != null) {
 | 
			
		||||
      return new Error("PRIMARY cannot be combined with tags");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If we provide a tags set send an error
 | 
			
		||||
    if(this._state.master == null) {
 | 
			
		||||
      return new Error("No replica set primary available for query with ReadPreference PRIMARY");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Checkout a writer
 | 
			
		||||
    return this.checkoutWriter();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // If we have specified to read from a secondary server grab a random one and read
 | 
			
		||||
  // from it, otherwise just pass the primary connection
 | 
			
		||||
  if((this.options.readSecondary || finalReadPreference == ReadPreference.SECONDARY_PREFERRED || finalReadPreference == ReadPreference.SECONDARY) && Object.keys(this._state.secondaries).length > 0) {
 | 
			
		||||
    // If we have tags, look for servers matching the specific tag
 | 
			
		||||
    if(this.strategyInstance != null) {
 | 
			
		||||
      // Only pick from secondaries
 | 
			
		||||
      var _secondaries = [];
 | 
			
		||||
      for(var key in this._state.secondaries) {
 | 
			
		||||
        _secondaries.push(this._state.secondaries[key]);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if(finalReadPreference == ReadPreference.SECONDARY) {
 | 
			
		||||
        // Check out the nearest from only the secondaries
 | 
			
		||||
        connection = this.strategyInstance.checkoutConnection(tags, _secondaries);
 | 
			
		||||
      } else {
 | 
			
		||||
        connection = this.strategyInstance.checkoutConnection(tags, _secondaries);
 | 
			
		||||
        // No candidate servers that match the tags, error
 | 
			
		||||
        if(connection == null || connection instanceof Error) {
 | 
			
		||||
          // No secondary server avilable, attemp to checkout a primary server
 | 
			
		||||
          connection = this.checkoutWriter();
 | 
			
		||||
          // If no connection return an error
 | 
			
		||||
          if(connection == null || connection instanceof Error) {
 | 
			
		||||
            return new Error("No replica set members available for query");
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    } else if(tags != null && typeof tags == 'object') {
 | 
			
		||||
      // Get connection
 | 
			
		||||
      connection = _pickFromTags(this, tags);// = function(self, readPreference, tags) {
 | 
			
		||||
      // No candidate servers that match the tags, error
 | 
			
		||||
      if(connection == null) {
 | 
			
		||||
        return new Error("No replica set members available for query");
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      connection = _roundRobin(this, tags);
 | 
			
		||||
    }
 | 
			
		||||
  } else if(finalReadPreference == ReadPreference.PRIMARY_PREFERRED) {
 | 
			
		||||
    // Check if there is a primary available and return that if possible
 | 
			
		||||
    connection = this.checkoutWriter();
 | 
			
		||||
    // If no connection available checkout a secondary
 | 
			
		||||
    if(connection == null || connection instanceof Error) {
 | 
			
		||||
      // If we have tags, look for servers matching the specific tag
 | 
			
		||||
      if(tags != null && typeof tags == 'object') {
 | 
			
		||||
        // Get connection
 | 
			
		||||
        connection = _pickFromTags(this, tags);// = function(self, readPreference, tags) {
 | 
			
		||||
        // No candidate servers that match the tags, error
 | 
			
		||||
        if(connection == null) {
 | 
			
		||||
          return new Error("No replica set members available for query");
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        connection = _roundRobin(this, tags);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  } else if(finalReadPreference == ReadPreference.SECONDARY_PREFERRED) {
 | 
			
		||||
    // If we have tags, look for servers matching the specific tag
 | 
			
		||||
    if(this.strategyInstance != null) {
 | 
			
		||||
      connection = this.strategyInstance.checkoutConnection(tags);
 | 
			
		||||
      
 | 
			
		||||
      // No candidate servers that match the tags, error
 | 
			
		||||
      if(connection == null || connection instanceof Error) {
 | 
			
		||||
        // No secondary server avilable, attemp to checkout a primary server
 | 
			
		||||
        connection = this.checkoutWriter();
 | 
			
		||||
        // If no connection return an error
 | 
			
		||||
        if(connection == null || connection instanceof Error) {
 | 
			
		||||
          var preferenceName = finalReadPreference == ReadPreference.SECONDARY ? 'secondary' : finalReadPreference;
 | 
			
		||||
          return new Error("No replica set member available for query with ReadPreference " + preferenceName + " and tags " + JSON.stringify(tags));
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    } else if(tags != null && typeof tags == 'object') {
 | 
			
		||||
      // Get connection
 | 
			
		||||
      connection = _pickFromTags(this, tags);// = function(self, readPreference, tags) {
 | 
			
		||||
      // No candidate servers that match the tags, error
 | 
			
		||||
      if(connection == null) {
 | 
			
		||||
        // No secondary server avilable, attemp to checkout a primary server
 | 
			
		||||
        connection = this.checkoutWriter();
 | 
			
		||||
        // If no connection return an error
 | 
			
		||||
        if(connection == null || connection instanceof Error) {
 | 
			
		||||
          var preferenceName = finalReadPreference == ReadPreference.SECONDARY ? 'secondary' : finalReadPreference;
 | 
			
		||||
          return new Error("No replica set member available for query with ReadPreference " + preferenceName + " and tags " + JSON.stringify(tags));
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  } else if(finalReadPreference == ReadPreference.NEAREST && this.strategyInstance != null) {
 | 
			
		||||
    connection = this.strategyInstance.checkoutConnection(tags);
 | 
			
		||||
  } else if(finalReadPreference == ReadPreference.NEAREST && this.strategyInstance == null) {
 | 
			
		||||
    return new Error("A strategy for calculating nearness must be enabled such as ping or statistical");
 | 
			
		||||
  } else if(finalReadPreference == ReadPreference.SECONDARY && Object.keys(this._state.secondaries).length == 0) {
 | 
			
		||||
    if(tags != null && typeof tags == 'object') {
 | 
			
		||||
      var preferenceName = finalReadPreference == ReadPreference.SECONDARY ? 'secondary' : finalReadPreference;
 | 
			
		||||
      return new Error("No replica set member available for query with ReadPreference " + preferenceName + " and tags " + JSON.stringify(tags));
 | 
			
		||||
    } else {
 | 
			
		||||
      return new Error("No replica set secondary available for query with ReadPreference SECONDARY");
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    connection = this.checkoutWriter();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Return the connection
 | 
			
		||||
  return connection;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
var _pickFromTags = function(self, tags) {
 | 
			
		||||
  // If we have an array or single tag selection
 | 
			
		||||
  var tagObjects = Array.isArray(tags) ? tags : [tags];
 | 
			
		||||
  // Iterate over all tags until we find a candidate server
 | 
			
		||||
  for(var _i = 0; _i < tagObjects.length; _i++) {
 | 
			
		||||
    // Grab a tag object
 | 
			
		||||
    var tagObject = tagObjects[_i];
 | 
			
		||||
    // Matching keys
 | 
			
		||||
    var matchingKeys = Object.keys(tagObject);
 | 
			
		||||
    // Match all the servers that match the provdided tags
 | 
			
		||||
    var keys = Object.keys(self._state.secondaries);
 | 
			
		||||
    var candidateServers = [];
 | 
			
		||||
 | 
			
		||||
    for(var i = 0; i < keys.length; i++) {
 | 
			
		||||
      var server = self._state.secondaries[keys[i]];
 | 
			
		||||
      // If we have tags match
 | 
			
		||||
      if(server.tags != null) {
 | 
			
		||||
        var matching = true;
 | 
			
		||||
        // Ensure we have all the values
 | 
			
		||||
        for(var j = 0; j < matchingKeys.length; j++) {
 | 
			
		||||
          if(server.tags[matchingKeys[j]] != tagObject[matchingKeys[j]]) {
 | 
			
		||||
            matching = false;
 | 
			
		||||
            break;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // If we have a match add it to the list of matching servers
 | 
			
		||||
        if(matching) {
 | 
			
		||||
          candidateServers.push(server);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If we have a candidate server return
 | 
			
		||||
    if(candidateServers.length > 0) {
 | 
			
		||||
      if(self.strategyInstance) return self.strategyInstance.checkoutConnection(tags, candidateServers);
 | 
			
		||||
      // Set instance to return
 | 
			
		||||
      return candidateServers[Math.floor(Math.random() * candidateServers.length)].checkoutReader();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // No connection found
 | 
			
		||||
  return null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Pick a secondary using round robin
 | 
			
		||||
 *
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
function _roundRobin (replset, tags) {
 | 
			
		||||
  var keys = Object.keys(replset._state.secondaries);
 | 
			
		||||
  // Update index
 | 
			
		||||
  replset._currentServerChoice = replset._currentServerChoice + 1;
 | 
			
		||||
  // Pick a server
 | 
			
		||||
  var key = keys[replset._currentServerChoice % keys.length];
 | 
			
		||||
 | 
			
		||||
  var conn = null != replset._state.secondaries[key]
 | 
			
		||||
    ? replset._state.secondaries[key].checkoutReader()
 | 
			
		||||
    : null;
 | 
			
		||||
 | 
			
		||||
  // If connection is null fallback to first available secondary
 | 
			
		||||
  if(null == conn) {
 | 
			
		||||
    conn = pickFirstConnectedSecondary(replset, tags);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return conn;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
var pickFirstConnectedSecondary = function pickFirstConnectedSecondary(self, tags) {
 | 
			
		||||
  var keys = Object.keys(self._state.secondaries);
 | 
			
		||||
  var connection;
 | 
			
		||||
 | 
			
		||||
  // Find first available reader if any
 | 
			
		||||
  for(var i = 0; i < keys.length; i++) {
 | 
			
		||||
    connection = self._state.secondaries[keys[i]].checkoutReader();
 | 
			
		||||
    if(connection) return connection;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // If we still have a null, read from primary if it's not secondary only
 | 
			
		||||
  if(self._readPreference == ReadPreference.SECONDARY_PREFERRED) {
 | 
			
		||||
    connection = self._state.master.checkoutReader();
 | 
			
		||||
    if(connection) return connection;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var preferenceName = self._readPreference == ReadPreference.SECONDARY_PREFERRED
 | 
			
		||||
    ? 'secondary'
 | 
			
		||||
    : self._readPreference;
 | 
			
		||||
 | 
			
		||||
  return new Error("No replica set member available for query with ReadPreference "
 | 
			
		||||
                  + preferenceName + " and tags " + JSON.stringify(tags));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get list of secondaries
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Object.defineProperty(ReplSet.prototype, "secondaries", {enumerable: true
 | 
			
		||||
  , get: function() {
 | 
			
		||||
      return utils.objectToArray(this._state.secondaries);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get list of secondaries
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Object.defineProperty(ReplSet.prototype, "arbiters", {enumerable: true
 | 
			
		||||
  , get: function() {
 | 
			
		||||
      return utils.objectToArray(this._state.arbiters);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										74
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/repl_set/repl_set_state.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										74
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/repl_set/repl_set_state.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,74 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Interval state object constructor
 | 
			
		||||
 *
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
var ReplSetState = function ReplSetState (replset) {
 | 
			
		||||
  this.errorMessages = [];
 | 
			
		||||
  this.secondaries = {};
 | 
			
		||||
  this.addresses = {};
 | 
			
		||||
  this.arbiters = {};
 | 
			
		||||
  this.passives = {};
 | 
			
		||||
  this.members = [];
 | 
			
		||||
  this.errors = {};
 | 
			
		||||
  this.setName = null;
 | 
			
		||||
  this.master = null;
 | 
			
		||||
  this.replset = replset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ReplSetState.prototype.hasValidServers = function() {
 | 
			
		||||
  var validServers = [];
 | 
			
		||||
  if(this.master && this.master.isConnected()) return true;
 | 
			
		||||
 | 
			
		||||
  if(this.secondaries) {
 | 
			
		||||
    var keys = Object.keys(this.secondaries)
 | 
			
		||||
    for(var i = 0; i < keys.length; i++) {
 | 
			
		||||
      if(this.secondaries[keys[i]].isConnected())
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ReplSetState.prototype.getAllReadServers = function() {
 | 
			
		||||
  var candidate_servers = [];
 | 
			
		||||
  for(var name in this.addresses) {
 | 
			
		||||
    candidate_servers.push(this.addresses[name]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Return all possible read candidates
 | 
			
		||||
  return candidate_servers;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ReplSetState.prototype.addServer = function(server, master) {
 | 
			
		||||
  server.name = master.me;
 | 
			
		||||
 | 
			
		||||
  if(master.ismaster) {
 | 
			
		||||
    this.master = server;
 | 
			
		||||
    this.addresses[server.name] = server;
 | 
			
		||||
    this.replset.emit('joined', "primary", master, server);
 | 
			
		||||
  } else if(master.secondary) {
 | 
			
		||||
    this.secondaries[server.name] = server;
 | 
			
		||||
    this.addresses[server.name] = server;
 | 
			
		||||
    this.replset.emit('joined', "secondary", master, server);
 | 
			
		||||
  } else if(master.arbiters) {
 | 
			
		||||
    this.arbiters[server.name] = server;
 | 
			
		||||
    this.addresses[server.name] = server;
 | 
			
		||||
    this.replset.emit('joined', "arbiter", master, server);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ReplSetState.prototype.contains = function(host) {
 | 
			
		||||
  return this.addresses[host] != null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ReplSetState.prototype.isPrimary = function(server) {
 | 
			
		||||
  return this.master && this.master.name == server.name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ReplSetState.prototype.isSecondary = function(server) {
 | 
			
		||||
  return this.secondaries[server.name] != null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.ReplSetState = ReplSetState;
 | 
			
		||||
							
								
								
									
										366
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/repl_set/strategies/ping_strategy.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										366
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/repl_set/strategies/ping_strategy.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,366 @@
 | 
			
		||||
var Server = require("../../server").Server
 | 
			
		||||
  , format = require('util').format;
 | 
			
		||||
 | 
			
		||||
// The ping strategy uses pings each server and records the
 | 
			
		||||
// elapsed time for the server so it can pick a server based on lowest
 | 
			
		||||
// return time for the db command {ping:true}
 | 
			
		||||
var PingStrategy = exports.PingStrategy = function(replicaset, secondaryAcceptableLatencyMS) {
 | 
			
		||||
  this.replicaset = replicaset;
 | 
			
		||||
  this.secondaryAcceptableLatencyMS = secondaryAcceptableLatencyMS;
 | 
			
		||||
  this.state = 'disconnected';
 | 
			
		||||
  // Interval of ping attempts
 | 
			
		||||
  this.pingInterval = replicaset.options.socketOptions.pingInterval || 5000;
 | 
			
		||||
  // Timeout for ping response, default - no timeout
 | 
			
		||||
  this.pingTimeout = replicaset.options.socketOptions.pingTimeout || null;
 | 
			
		||||
  // Class instance
 | 
			
		||||
  this.Db = require("../../../db").Db;
 | 
			
		||||
  // Active db connections
 | 
			
		||||
  this.dbs = {};
 | 
			
		||||
  // Current server index
 | 
			
		||||
  this.index = 0;
 | 
			
		||||
  // Logger api
 | 
			
		||||
  this.Logger = null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Starts any needed code
 | 
			
		||||
PingStrategy.prototype.start = function(callback) {
 | 
			
		||||
  // already running?
 | 
			
		||||
  if ('connected' == this.state) return;
 | 
			
		||||
 | 
			
		||||
  this.state = 'connected';
 | 
			
		||||
 | 
			
		||||
  // Start ping server
 | 
			
		||||
  this._pingServer(callback);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Stops and kills any processes running
 | 
			
		||||
PingStrategy.prototype.stop = function(callback) {
 | 
			
		||||
  // Stop the ping process
 | 
			
		||||
  this.state = 'disconnected';
 | 
			
		||||
 | 
			
		||||
  // Stop all the server instances
 | 
			
		||||
  for(var key in this.dbs) {
 | 
			
		||||
    this.dbs[key].close();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // optional callback
 | 
			
		||||
  callback && callback(null, null);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PingStrategy.prototype.checkoutConnection = function(tags, secondaryCandidates) {
 | 
			
		||||
  // Servers are picked based on the lowest ping time and then servers that lower than that + secondaryAcceptableLatencyMS
 | 
			
		||||
  // Create a list of candidat servers, containing the primary if available
 | 
			
		||||
  var candidateServers = [];
 | 
			
		||||
  var self = this;
 | 
			
		||||
 | 
			
		||||
  // If we have not provided a list of candidate servers use the default setup
 | 
			
		||||
  if(!Array.isArray(secondaryCandidates)) {
 | 
			
		||||
    candidateServers = this.replicaset._state.master != null ? [this.replicaset._state.master] : [];
 | 
			
		||||
    // Add all the secondaries
 | 
			
		||||
    var keys = Object.keys(this.replicaset._state.secondaries);
 | 
			
		||||
    for(var i = 0; i < keys.length; i++) {
 | 
			
		||||
      candidateServers.push(this.replicaset._state.secondaries[keys[i]])
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    candidateServers = secondaryCandidates;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Final list of eligable server
 | 
			
		||||
  var finalCandidates = [];
 | 
			
		||||
 | 
			
		||||
  // If we have tags filter by tags
 | 
			
		||||
  if(tags != null && typeof tags == 'object') {
 | 
			
		||||
    // If we have an array or single tag selection
 | 
			
		||||
    var tagObjects = Array.isArray(tags) ? tags : [tags];
 | 
			
		||||
    // Iterate over all tags until we find a candidate server
 | 
			
		||||
    for(var _i = 0; _i < tagObjects.length; _i++) {
 | 
			
		||||
      // Grab a tag object
 | 
			
		||||
      var tagObject = tagObjects[_i];
 | 
			
		||||
      // Matching keys
 | 
			
		||||
      var matchingKeys = Object.keys(tagObject);
 | 
			
		||||
      // Remove any that are not tagged correctly
 | 
			
		||||
      for(var i = 0; i < candidateServers.length; i++) {
 | 
			
		||||
        var server = candidateServers[i];
 | 
			
		||||
        // If we have tags match
 | 
			
		||||
        if(server.tags != null) {
 | 
			
		||||
          var matching = true;
 | 
			
		||||
 | 
			
		||||
          // Ensure we have all the values
 | 
			
		||||
          for(var j = 0; j < matchingKeys.length; j++) {
 | 
			
		||||
            if(server.tags[matchingKeys[j]] != tagObject[matchingKeys[j]]) {
 | 
			
		||||
              matching = false;
 | 
			
		||||
              break;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          // If we have a match add it to the list of matching servers
 | 
			
		||||
          if(matching) {
 | 
			
		||||
            finalCandidates.push(server);
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    // Final array candidates
 | 
			
		||||
    var finalCandidates = candidateServers;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Filter out any non-connected servers
 | 
			
		||||
  finalCandidates = finalCandidates.filter(function(s) {
 | 
			
		||||
    return s.isConnected();
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  // Sort by ping time
 | 
			
		||||
  finalCandidates.sort(function(a, b) {
 | 
			
		||||
    return a.runtimeStats['pingMs'] > b.runtimeStats['pingMs'];
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  if(0 === finalCandidates.length)
 | 
			
		||||
    return new Error("No replica set members available for query");
 | 
			
		||||
 | 
			
		||||
  // find lowest server with a ping time
 | 
			
		||||
  var lowest = finalCandidates.filter(function (server) {
 | 
			
		||||
    return undefined != server.runtimeStats.pingMs;
 | 
			
		||||
  })[0];
 | 
			
		||||
 | 
			
		||||
  if(!lowest) {
 | 
			
		||||
    lowest = finalCandidates[0];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // convert to integer
 | 
			
		||||
  var lowestPing = lowest.runtimeStats.pingMs | 0;
 | 
			
		||||
  
 | 
			
		||||
  // determine acceptable latency
 | 
			
		||||
  var acceptable = lowestPing + this.secondaryAcceptableLatencyMS;
 | 
			
		||||
 | 
			
		||||
  // remove any server responding slower than acceptable
 | 
			
		||||
  var len = finalCandidates.length;
 | 
			
		||||
  while(len--) {
 | 
			
		||||
    if(finalCandidates[len].runtimeStats['pingMs'] > acceptable) {
 | 
			
		||||
      finalCandidates.splice(len, 1);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(self.logger && self.logger.debug) {    
 | 
			
		||||
    self.logger.debug("Ping strategy selection order for tags", tags);
 | 
			
		||||
    finalCandidates.forEach(function(c) {
 | 
			
		||||
      self.logger.debug(format("%s:%s = %s ms", c.host, c.port, c.runtimeStats['pingMs']), null);
 | 
			
		||||
    })    
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // If no candidates available return an error
 | 
			
		||||
  if(finalCandidates.length == 0)
 | 
			
		||||
    return new Error("No replica set members available for query");
 | 
			
		||||
 | 
			
		||||
  // Ensure no we don't overflow
 | 
			
		||||
  this.index = this.index % finalCandidates.length
 | 
			
		||||
  // Pick a random acceptable server  
 | 
			
		||||
  var connection = finalCandidates[this.index].checkoutReader();
 | 
			
		||||
  // Point to next candidate (round robin style)
 | 
			
		||||
  this.index = this.index + 1;
 | 
			
		||||
 | 
			
		||||
  if(self.logger && self.logger.debug) {    
 | 
			
		||||
    if(connection)
 | 
			
		||||
      self.logger.debug(format("picked server %s:%s", connection.socketOptions.host, connection.socketOptions.port));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return connection;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PingStrategy.prototype._pingServer = function(callback) {
 | 
			
		||||
  var self = this;
 | 
			
		||||
 | 
			
		||||
  // Ping server function
 | 
			
		||||
  var pingFunction = function() {
 | 
			
		||||
    // Our state changed to disconnected or destroyed return
 | 
			
		||||
    if(self.state == 'disconnected' || self.state == 'destroyed') return;
 | 
			
		||||
    // If the replicaset is destroyed return
 | 
			
		||||
    if(self.replicaset.isDestroyed() || self.replicaset._serverState == 'disconnected') return
 | 
			
		||||
 | 
			
		||||
    // Create a list of all servers we can send the ismaster command to
 | 
			
		||||
    var allServers = self.replicaset._state.master != null ? [self.replicaset._state.master] : [];
 | 
			
		||||
 | 
			
		||||
    // Secondary keys
 | 
			
		||||
    var keys = Object.keys(self.replicaset._state.secondaries);
 | 
			
		||||
    // Add all secondaries
 | 
			
		||||
    for(var i = 0; i < keys.length; i++) {
 | 
			
		||||
      allServers.push(self.replicaset._state.secondaries[keys[i]]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Number of server entries
 | 
			
		||||
    var numberOfEntries = allServers.length;
 | 
			
		||||
 | 
			
		||||
    // We got keys
 | 
			
		||||
    for(var i = 0; i < allServers.length; i++) {
 | 
			
		||||
 | 
			
		||||
      // We got a server instance
 | 
			
		||||
      var server = allServers[i];
 | 
			
		||||
 | 
			
		||||
      // Create a new server object, avoid using internal connections as they might
 | 
			
		||||
      // be in an illegal state
 | 
			
		||||
      new function(serverInstance) {
 | 
			
		||||
        var _db = self.dbs[serverInstance.host + ":" + serverInstance.port];
 | 
			
		||||
        // If we have a db
 | 
			
		||||
        if(_db != null) {
 | 
			
		||||
          // Startup time of the command
 | 
			
		||||
          var startTime = Date.now();
 | 
			
		||||
 | 
			
		||||
          // Execute ping command in own scope
 | 
			
		||||
          var _ping = function(__db, __serverInstance) {
 | 
			
		||||
 | 
			
		||||
            // Server unavailable. Checks only if pingTimeout defined & greater than 0
 | 
			
		||||
            var _failTimer = self.pingTimeout ? setTimeout(function () {
 | 
			
		||||
              if(null != __serverInstance.runtimeStats && __serverInstance.isConnected()) {
 | 
			
		||||
                __serverInstance.close();
 | 
			
		||||
              }
 | 
			
		||||
            }, self.pingTimeout) : null;
 | 
			
		||||
 | 
			
		||||
            // Execute ping on this connection
 | 
			
		||||
            __db.executeDbCommand({ping:1}, {failFast:true}, function(err) {
 | 
			
		||||
 | 
			
		||||
              // Server available
 | 
			
		||||
              clearTimeout(_failTimer);
 | 
			
		||||
 | 
			
		||||
              // Emit the ping
 | 
			
		||||
              self.replicaset.emit("ping", err, serverInstance);
 | 
			
		||||
 | 
			
		||||
              if(err) {
 | 
			
		||||
                delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port];
 | 
			
		||||
                __db.close();
 | 
			
		||||
                return done();
 | 
			
		||||
              }
 | 
			
		||||
 | 
			
		||||
              if(null != __serverInstance.runtimeStats && __serverInstance.isConnected()) {
 | 
			
		||||
                __serverInstance.runtimeStats['pingMs'] = Date.now() - startTime;
 | 
			
		||||
              }
 | 
			
		||||
 | 
			
		||||
              __db.executeDbCommand({ismaster:1}, {failFast:true}, function(err, result) {
 | 
			
		||||
                // Emit the ping
 | 
			
		||||
                self.replicaset.emit("ping_ismaster", err, result, serverInstance);
 | 
			
		||||
 | 
			
		||||
                if(err) {
 | 
			
		||||
                  delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port];
 | 
			
		||||
                  __db.close();
 | 
			
		||||
                  return done();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Process the ismaster for the server
 | 
			
		||||
                if(result && result.documents && self.replicaset.processIsMaster) {
 | 
			
		||||
                  self.replicaset.processIsMaster(__serverInstance, result.documents[0]);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Done with the pinging
 | 
			
		||||
                done();
 | 
			
		||||
              });
 | 
			
		||||
            });            
 | 
			
		||||
          };
 | 
			
		||||
          // Ping
 | 
			
		||||
          _ping(_db, serverInstance);
 | 
			
		||||
        } else {
 | 
			
		||||
          var connectTimeoutMS = self.replicaset.options.socketOptions 
 | 
			
		||||
            ? self.replicaset.options.socketOptions.connectTimeoutMS : 0
 | 
			
		||||
 | 
			
		||||
          // Create a new master connection
 | 
			
		||||
          var _server = new Server(serverInstance.host, serverInstance.port, {
 | 
			
		||||
            auto_reconnect: false,
 | 
			
		||||
            returnIsMasterResults: true,
 | 
			
		||||
            slaveOk: true,
 | 
			
		||||
            poolSize: 1,
 | 
			
		||||
            socketOptions: { connectTimeoutMS: connectTimeoutMS },
 | 
			
		||||
            ssl: self.replicaset.options.ssl,
 | 
			
		||||
            sslValidate: self.replicaset.options.sslValidate,
 | 
			
		||||
            sslCA: self.replicaset.options.sslCA,
 | 
			
		||||
            sslCert: self.replicaset.options.sslCert,
 | 
			
		||||
            sslKey: self.replicaset.options.sslKey,
 | 
			
		||||
            sslPass: self.replicaset.options.sslPass
 | 
			
		||||
          });
 | 
			
		||||
 | 
			
		||||
          // Create Db instance        
 | 
			
		||||
          var _db = new self.Db('local', _server, { safe: true });
 | 
			
		||||
          _db.on("close", function() {
 | 
			
		||||
            delete self.dbs[this.serverConfig.host + ":" + this.serverConfig.port];
 | 
			
		||||
          })
 | 
			
		||||
 | 
			
		||||
          var _ping = function(__db, __serverInstance) {
 | 
			
		||||
            if(self.state == 'disconnected') {
 | 
			
		||||
              self.stop();
 | 
			
		||||
              return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            __db.open(function(err, db) {  
 | 
			
		||||
              // Emit ping connect
 | 
			
		||||
              self.replicaset.emit("ping_connect", err, __serverInstance);
 | 
			
		||||
 | 
			
		||||
              if(self.state == 'disconnected' && __db != null) {
 | 
			
		||||
                return __db.close();
 | 
			
		||||
              }
 | 
			
		||||
 | 
			
		||||
              if(err) {
 | 
			
		||||
                delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port];
 | 
			
		||||
                __db.close();
 | 
			
		||||
                return done();
 | 
			
		||||
              }
 | 
			
		||||
 | 
			
		||||
              // Save instance
 | 
			
		||||
              self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port] = __db;
 | 
			
		||||
 | 
			
		||||
              // Startup time of the command
 | 
			
		||||
              var startTime = Date.now();
 | 
			
		||||
 | 
			
		||||
              // Execute ping on this connection
 | 
			
		||||
              __db.executeDbCommand({ping:1}, {failFast:true}, function(err) {
 | 
			
		||||
                self.replicaset.emit("ping", err, __serverInstance);
 | 
			
		||||
                
 | 
			
		||||
                if(err) {
 | 
			
		||||
                  delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port];
 | 
			
		||||
                  __db.close();
 | 
			
		||||
                  return done();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if(null != __serverInstance.runtimeStats && __serverInstance.isConnected()) {
 | 
			
		||||
                  __serverInstance.runtimeStats['pingMs'] = Date.now() - startTime;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                __db.executeDbCommand({ismaster:1}, {failFast:true}, function(err, result) {
 | 
			
		||||
                  self.replicaset.emit("ping_ismaster", err, result, __serverInstance);
 | 
			
		||||
 | 
			
		||||
                  if(err) {
 | 
			
		||||
                    delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port];
 | 
			
		||||
                    __db.close();
 | 
			
		||||
                    return done();
 | 
			
		||||
                  }
 | 
			
		||||
    
 | 
			
		||||
                  // Process the ismaster for the server
 | 
			
		||||
                  if(result && result.documents && self.replicaset.processIsMaster) {
 | 
			
		||||
                    self.replicaset.processIsMaster(__serverInstance, result.documents[0]);
 | 
			
		||||
                  }
 | 
			
		||||
 | 
			
		||||
                  // Done with the pinging
 | 
			
		||||
                  done();
 | 
			
		||||
                });
 | 
			
		||||
              });
 | 
			
		||||
            });            
 | 
			
		||||
          };
 | 
			
		||||
 | 
			
		||||
          // Ping the server
 | 
			
		||||
          _ping(_db, serverInstance);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        function done() {
 | 
			
		||||
          // Adjust the number of checks
 | 
			
		||||
          numberOfEntries--;
 | 
			
		||||
 | 
			
		||||
          // If we are done with all results coming back trigger ping again
 | 
			
		||||
          if(0 === numberOfEntries && 'connected' == self.state) {
 | 
			
		||||
            setTimeout(pingFunction, self.pingInterval);
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }(server);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Start pingFunction
 | 
			
		||||
  pingFunction();
 | 
			
		||||
 | 
			
		||||
  callback && callback(null);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										93
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/repl_set/strategies/statistics_strategy.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										93
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/repl_set/strategies/statistics_strategy.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,93 @@
 | 
			
		||||
// The Statistics strategy uses the measure of each end-start time for each
 | 
			
		||||
// query executed against the db to calculate the mean, variance and standard deviation
 | 
			
		||||
// and pick the server which the lowest mean and deviation
 | 
			
		||||
var StatisticsStrategy = exports.StatisticsStrategy = function(replicaset) {
 | 
			
		||||
  this.replicaset = replicaset;
 | 
			
		||||
  // Logger api
 | 
			
		||||
  this.Logger = null;  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Starts any needed code
 | 
			
		||||
StatisticsStrategy.prototype.start = function(callback) {
 | 
			
		||||
  callback && callback(null, null);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
StatisticsStrategy.prototype.stop = function(callback) {
 | 
			
		||||
  callback && callback(null, null);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
StatisticsStrategy.prototype.checkoutConnection = function(tags, secondaryCandidates) {
 | 
			
		||||
  // Servers are picked based on the lowest ping time and then servers that lower than that + secondaryAcceptableLatencyMS
 | 
			
		||||
  // Create a list of candidat servers, containing the primary if available
 | 
			
		||||
  var candidateServers = [];
 | 
			
		||||
 | 
			
		||||
  // If we have not provided a list of candidate servers use the default setup
 | 
			
		||||
  if(!Array.isArray(secondaryCandidates)) {
 | 
			
		||||
    candidateServers = this.replicaset._state.master != null ? [this.replicaset._state.master] : [];
 | 
			
		||||
    // Add all the secondaries
 | 
			
		||||
    var keys = Object.keys(this.replicaset._state.secondaries);
 | 
			
		||||
    for(var i = 0; i < keys.length; i++) {
 | 
			
		||||
      candidateServers.push(this.replicaset._state.secondaries[keys[i]])
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    candidateServers = secondaryCandidates;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Final list of eligable server
 | 
			
		||||
  var finalCandidates = [];
 | 
			
		||||
 | 
			
		||||
  // If we have tags filter by tags
 | 
			
		||||
  if(tags != null && typeof tags == 'object') {
 | 
			
		||||
    // If we have an array or single tag selection
 | 
			
		||||
    var tagObjects = Array.isArray(tags) ? tags : [tags];
 | 
			
		||||
    // Iterate over all tags until we find a candidate server
 | 
			
		||||
    for(var _i = 0; _i < tagObjects.length; _i++) {
 | 
			
		||||
      // Grab a tag object
 | 
			
		||||
      var tagObject = tagObjects[_i];
 | 
			
		||||
      // Matching keys
 | 
			
		||||
      var matchingKeys = Object.keys(tagObject);
 | 
			
		||||
      // Remove any that are not tagged correctly
 | 
			
		||||
      for(var i = 0; i < candidateServers.length; i++) {
 | 
			
		||||
        var server = candidateServers[i];
 | 
			
		||||
        // If we have tags match
 | 
			
		||||
        if(server.tags != null) {
 | 
			
		||||
          var matching = true;
 | 
			
		||||
 | 
			
		||||
          // Ensure we have all the values
 | 
			
		||||
          for(var j = 0; j < matchingKeys.length; j++) {
 | 
			
		||||
            if(server.tags[matchingKeys[j]] != tagObject[matchingKeys[j]]) {
 | 
			
		||||
              matching = false;
 | 
			
		||||
              break;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          // If we have a match add it to the list of matching servers
 | 
			
		||||
          if(matching) {
 | 
			
		||||
            finalCandidates.push(server);
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    // Final array candidates
 | 
			
		||||
    var finalCandidates = candidateServers;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  finalCandidates.sort(function(a, b) {
 | 
			
		||||
    return a.runtimeStats.queryStats.sScore > b.runtimeStats.queryStats.sScore;
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // If no candidates available return an error
 | 
			
		||||
  if(finalCandidates.length == 0) return new Error("No replica set members available for query");
 | 
			
		||||
 | 
			
		||||
  var bestCandidates = [finalCandidates[0]];
 | 
			
		||||
  for (var i = 1; i < finalCandidates.length; ++i) {
 | 
			
		||||
    if (finalCandidates[i].runtimeStats.queryStats.sScore > finalCandidates[i - 1].runtimeStats.queryStats.sScore) {
 | 
			
		||||
      break;
 | 
			
		||||
    } else {
 | 
			
		||||
      bestCandidates.push(finalCandidates[i]);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return bestCandidates[Math.floor(Math.random() * bestCandidates.length)].checkoutReader();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										950
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/server.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										950
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/server.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,950 @@
 | 
			
		||||
var Connection = require('./connection').Connection,
 | 
			
		||||
  ReadPreference = require('./read_preference').ReadPreference,
 | 
			
		||||
  DbCommand = require('../commands/db_command').DbCommand,
 | 
			
		||||
  MongoReply = require('../responses/mongo_reply').MongoReply,
 | 
			
		||||
  ConnectionPool = require('./connection_pool').ConnectionPool,
 | 
			
		||||
  EventEmitter = require('events').EventEmitter,
 | 
			
		||||
  ServerCapabilities = require('./server_capabilities').ServerCapabilities,
 | 
			
		||||
  Base = require('./base').Base,
 | 
			
		||||
  format = require('util').format,
 | 
			
		||||
  utils = require('../utils'),
 | 
			
		||||
  timers = require('timers'),
 | 
			
		||||
  inherits = require('util').inherits;
 | 
			
		||||
 | 
			
		||||
// Set processor, setImmediate if 0.10 otherwise nextTick
 | 
			
		||||
var processor = require('../utils').processor();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class representing a single MongoDB Server connection
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **ssl** {Boolean, default:false}, use ssl connection (needs to have a mongod server with ssl support)
 | 
			
		||||
 *  - **sslValidate** {Boolean, default:false}, validate mongod server certificate against ca (needs to have a mongod server with ssl support, 2.4 or higher)
 | 
			
		||||
 *  - **sslCA** {Array, default:null}, Array of valid certificates either as Buffers or Strings (needs to have a mongod server with ssl support, 2.4 or higher)
 | 
			
		||||
 *  - **sslCert** {Buffer/String, default:null}, String or buffer containing the certificate we wish to present (needs to have a mongod server with ssl support, 2.4 or higher)
 | 
			
		||||
 *  - **sslKey** {Buffer/String, default:null}, String or buffer containing the certificate private key we wish to present (needs to have a mongod server with ssl support, 2.4 or higher)
 | 
			
		||||
 *  - **sslPass** {Buffer/String, default:null}, String or buffer containing the certificate password (needs to have a mongod server with ssl support, 2.4 or higher)
 | 
			
		||||
 *  - **poolSize** {Number, default:5}, number of connections in the connection pool, set to 5 as default for legacy reasons.
 | 
			
		||||
 *  - **socketOptions** {Object, default:null}, an object containing socket options to use (noDelay:(boolean), keepAlive:(number), connectTimeoutMS:(number), socketTimeoutMS:(number))
 | 
			
		||||
 *  - **logger** {Object, default:null}, an object representing a logger that you want to use, needs to support functions debug, log, error **({error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}})**.
 | 
			
		||||
 *  - **auto_reconnect** {Boolean, default:false}, reconnect on error.
 | 
			
		||||
 *  - **disableDriverBSONSizeCheck** {Boolean, default:false}, force the server to error if the BSON message is to big
 | 
			
		||||
 *
 | 
			
		||||
 * @class Represents a Server connection.
 | 
			
		||||
 * @param {String} host the server host
 | 
			
		||||
 * @param {Number} port the server port
 | 
			
		||||
 * @param {Object} [options] optional options for insert command
 | 
			
		||||
 */
 | 
			
		||||
function Server(host, port, options) {
 | 
			
		||||
  // Set up Server instance
 | 
			
		||||
  if(!(this instanceof Server)) return new Server(host, port, options);
 | 
			
		||||
 | 
			
		||||
  // Set up event emitter
 | 
			
		||||
  Base.call(this);
 | 
			
		||||
 | 
			
		||||
  // Ensure correct values
 | 
			
		||||
  if(port != null && typeof port == 'object') {
 | 
			
		||||
    options = port;
 | 
			
		||||
    port = Connection.DEFAULT_PORT;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var self = this;
 | 
			
		||||
  this.host = host;
 | 
			
		||||
  this.port = port;
 | 
			
		||||
  this.options = options == null ? {} : options;
 | 
			
		||||
  this.internalConnection;
 | 
			
		||||
  this.internalMaster = false;
 | 
			
		||||
  this.connected = false;  
 | 
			
		||||
  this.poolSize = this.options.poolSize == null ? 5 : this.options.poolSize;
 | 
			
		||||
  this.disableDriverBSONSizeCheck = this.options.disableDriverBSONSizeCheck != null ? this.options.disableDriverBSONSizeCheck : false;
 | 
			
		||||
  this._used = false;
 | 
			
		||||
  this.replicasetInstance = null;
 | 
			
		||||
 | 
			
		||||
  // Emit open setup
 | 
			
		||||
  this.emitOpen = this.options.emitOpen || true;
 | 
			
		||||
  // Set ssl as connection method
 | 
			
		||||
  this.ssl = this.options.ssl == null ? false : this.options.ssl;
 | 
			
		||||
  // Set ssl validation
 | 
			
		||||
  this.sslValidate = this.options.sslValidate == null ? false : this.options.sslValidate;
 | 
			
		||||
  // Set the ssl certificate authority (array of Buffer/String keys)
 | 
			
		||||
  this.sslCA = Array.isArray(this.options.sslCA) ? this.options.sslCA : null;
 | 
			
		||||
  // Certificate to present to the server
 | 
			
		||||
  this.sslCert = this.options.sslCert;
 | 
			
		||||
  // Certificate private key if in separate file
 | 
			
		||||
  this.sslKey = this.options.sslKey;
 | 
			
		||||
  // Password to unlock private key
 | 
			
		||||
  this.sslPass = this.options.sslPass;
 | 
			
		||||
  // Server capabilities
 | 
			
		||||
  this.serverCapabilities = null;
 | 
			
		||||
  // Set server name
 | 
			
		||||
  this.name = format("%s:%s", host, port);
 | 
			
		||||
 | 
			
		||||
  // Ensure we are not trying to validate with no list of certificates
 | 
			
		||||
  if(this.sslValidate && (!Array.isArray(this.sslCA) || this.sslCA.length == 0)) {
 | 
			
		||||
    throw new Error("The driver expects an Array of CA certificates in the sslCA parameter when enabling sslValidate");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Contains the isMaster information returned from the server
 | 
			
		||||
  this.isMasterDoc;
 | 
			
		||||
 | 
			
		||||
  // Set default connection pool options
 | 
			
		||||
  this.socketOptions = this.options.socketOptions != null ? this.options.socketOptions : {};
 | 
			
		||||
  if(this.disableDriverBSONSizeCheck) this.socketOptions.disableDriverBSONSizeCheck = this.disableDriverBSONSizeCheck;
 | 
			
		||||
 | 
			
		||||
  // Set ssl up if it's defined
 | 
			
		||||
  if(this.ssl) {
 | 
			
		||||
    this.socketOptions.ssl = true;
 | 
			
		||||
    // Set ssl validation
 | 
			
		||||
    this.socketOptions.sslValidate = this.sslValidate == null ? false : this.sslValidate;
 | 
			
		||||
    // Set the ssl certificate authority (array of Buffer/String keys)
 | 
			
		||||
    this.socketOptions.sslCA = Array.isArray(this.sslCA) ? this.sslCA : null;
 | 
			
		||||
    // Set certificate to present
 | 
			
		||||
    this.socketOptions.sslCert = this.sslCert;
 | 
			
		||||
    // Set certificate to present
 | 
			
		||||
    this.socketOptions.sslKey = this.sslKey;
 | 
			
		||||
    // Password to unlock private key
 | 
			
		||||
    this.socketOptions.sslPass = this.sslPass;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Set up logger if any set
 | 
			
		||||
  this.logger = this.options.logger != null
 | 
			
		||||
    && (typeof this.options.logger.debug == 'function')
 | 
			
		||||
    && (typeof this.options.logger.error == 'function')
 | 
			
		||||
    && (typeof this.options.logger.log == 'function')
 | 
			
		||||
      ? this.options.logger : {error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}};
 | 
			
		||||
 | 
			
		||||
  // Just keeps list of events we allow
 | 
			
		||||
  this.eventHandlers = {error:[], parseError:[], poolReady:[], message:[], close:[], timeout:[]};
 | 
			
		||||
  // Internal state of server connection
 | 
			
		||||
  this._serverState = 'disconnected';
 | 
			
		||||
  // Contains state information about server connection
 | 
			
		||||
  this._state = {'runtimeStats': {'queryStats':new RunningStats()}};
 | 
			
		||||
  // Do we record server stats or not
 | 
			
		||||
  this.recordQueryStats = false;
 | 
			
		||||
 | 
			
		||||
  // Allow setting the socketTimeoutMS on all connections
 | 
			
		||||
  // to work around issues such as secondaries blocking due to compaction
 | 
			
		||||
  utils.setSocketTimeoutProperty(this, this.socketOptions);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
inherits(Server, Base);
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//  Deprecated, USE ReadPreferences class
 | 
			
		||||
//
 | 
			
		||||
Server.READ_PRIMARY = ReadPreference.PRIMARY;
 | 
			
		||||
Server.READ_SECONDARY = ReadPreference.SECONDARY_PREFERRED;
 | 
			
		||||
Server.READ_SECONDARY_ONLY = ReadPreference.SECONDARY;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Always ourselves
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Server.prototype.setReadPreference = function(readPreference) {
 | 
			
		||||
  this._readPreference = readPreference;  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Server.prototype.isMongos = function() {
 | 
			
		||||
  return this.isMasterDoc != null && this.isMasterDoc['msg'] == "isdbgrid" ? true : false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Server.prototype._isUsed = function() {
 | 
			
		||||
  return this._used;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Server.prototype.close = function(callback) {
 | 
			
		||||
  // Set server status as disconnected
 | 
			
		||||
  this._serverState = 'destroyed';
 | 
			
		||||
  // Remove all local listeners
 | 
			
		||||
  this.removeAllListeners();
 | 
			
		||||
 | 
			
		||||
  if(this.connectionPool != null) {
 | 
			
		||||
    // Remove all the listeners on the pool so it does not fire messages all over the place
 | 
			
		||||
    this.connectionPool.removeAllEventListeners();
 | 
			
		||||
    // Close the connection if it's open
 | 
			
		||||
    this.connectionPool.stop(true);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Emit close event
 | 
			
		||||
  if(this.db && !this.isSetMember()) {
 | 
			
		||||
    var self = this;
 | 
			
		||||
    processor(function() {
 | 
			
		||||
      self._emitAcrossAllDbInstances(self, null, "close", null, null, true)
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    // Flush out any remaining call handlers
 | 
			
		||||
    self._flushAllCallHandlers(utils.toError("Connection Closed By Application"));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Peform callback if present
 | 
			
		||||
  if(typeof callback === 'function') callback(null);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Server.prototype.isDestroyed = function() {
 | 
			
		||||
  return this._serverState == 'destroyed';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Server.prototype.isConnected = function() {
 | 
			
		||||
  return this.connectionPool != null && this.connectionPool.isConnected();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Server.prototype.canWrite = Server.prototype.isConnected;
 | 
			
		||||
Server.prototype.canRead = Server.prototype.isConnected;
 | 
			
		||||
 | 
			
		||||
Server.prototype.isAutoReconnect = function() {
 | 
			
		||||
  if(this.isSetMember()) return false;
 | 
			
		||||
  return this.options.auto_reconnect != null ? this.options.auto_reconnect : true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Server.prototype.allServerInstances = function() {
 | 
			
		||||
  return [this];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Server.prototype.isSetMember = function() {
 | 
			
		||||
  return this.replicasetInstance != null || this.mongosInstance != null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Server.prototype.setSocketOptions = function(options) {
 | 
			
		||||
  var connections = this.allRawConnections();
 | 
			
		||||
  for(var i = 0; i < connections.length; i++) {
 | 
			
		||||
    connections[i].setSocketOptions(options);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Assigns a replica set to this `server`.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {ReplSet} replset
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Server.prototype.assignReplicaSet = function (replset) {
 | 
			
		||||
  this.replicasetInstance = replset;
 | 
			
		||||
  this.inheritReplSetOptionsFrom(replset);
 | 
			
		||||
  this.enableRecordQueryStats(replset.recordQueryStats);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Takes needed options from `replset` and overwrites
 | 
			
		||||
 * our own options.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {ReplSet} replset
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Server.prototype.inheritReplSetOptionsFrom = function (replset) {
 | 
			
		||||
  this.socketOptions = {};
 | 
			
		||||
  this.socketOptions.connectTimeoutMS = replset.options.socketOptions.connectTimeoutMS || 30000;
 | 
			
		||||
 | 
			
		||||
  if(replset.options.ssl) {
 | 
			
		||||
    // Set ssl on
 | 
			
		||||
    this.socketOptions.ssl = true;
 | 
			
		||||
    // Set ssl validation
 | 
			
		||||
    this.socketOptions.sslValidate = replset.options.sslValidate == null ? false : replset.options.sslValidate;
 | 
			
		||||
    // Set the ssl certificate authority (array of Buffer/String keys)
 | 
			
		||||
    this.socketOptions.sslCA = Array.isArray(replset.options.sslCA) ? replset.options.sslCA : null;
 | 
			
		||||
    // Set certificate to present
 | 
			
		||||
    this.socketOptions.sslCert = replset.options.sslCert;
 | 
			
		||||
    // Set certificate to present
 | 
			
		||||
    this.socketOptions.sslKey = replset.options.sslKey;
 | 
			
		||||
    // Password to unlock private key
 | 
			
		||||
    this.socketOptions.sslPass = replset.options.sslPass;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // If a socket option object exists clone it
 | 
			
		||||
  if(utils.isObject(replset.options.socketOptions)) {
 | 
			
		||||
    var keys = Object.keys(replset.options.socketOptions);
 | 
			
		||||
    for(var i = 0; i < keys.length; i++)
 | 
			
		||||
      this.socketOptions[keys[i]] = replset.options.socketOptions[keys[i]];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Opens this server connection.
 | 
			
		||||
 *
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Server.prototype.connect = function(dbInstance, options, callback) {
 | 
			
		||||
  if('function' === typeof options) callback = options, options = {};
 | 
			
		||||
  if(options == null) options = {};
 | 
			
		||||
  if(!('function' === typeof callback)) callback = null;
 | 
			
		||||
  var self = this;
 | 
			
		||||
  // Save the options
 | 
			
		||||
  this.options = options;
 | 
			
		||||
 | 
			
		||||
  // Currently needed to work around problems with multiple connections in a pool with ssl
 | 
			
		||||
  // TODO fix if possible
 | 
			
		||||
  if(this.ssl == true) {
 | 
			
		||||
    // Set up socket options for ssl
 | 
			
		||||
    this.socketOptions.ssl = true;
 | 
			
		||||
    // Set ssl validation
 | 
			
		||||
    this.socketOptions.sslValidate = this.sslValidate == null ? false : this.sslValidate;
 | 
			
		||||
    // Set the ssl certificate authority (array of Buffer/String keys)
 | 
			
		||||
    this.socketOptions.sslCA = Array.isArray(this.sslCA) ? this.sslCA : null;
 | 
			
		||||
    // Set certificate to present
 | 
			
		||||
    this.socketOptions.sslCert = this.sslCert;
 | 
			
		||||
    // Set certificate to present
 | 
			
		||||
    this.socketOptions.sslKey = this.sslKey;
 | 
			
		||||
    // Password to unlock private key
 | 
			
		||||
    this.socketOptions.sslPass = this.sslPass;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Let's connect
 | 
			
		||||
  var server = this;
 | 
			
		||||
  // Let's us override the main receiver of events
 | 
			
		||||
  var eventReceiver = options.eventReceiver != null ? options.eventReceiver : this;
 | 
			
		||||
  // Save reference to dbInstance
 | 
			
		||||
  this.db = dbInstance;  // `db` property matches ReplSet and Mongos
 | 
			
		||||
  this.dbInstances = [dbInstance];
 | 
			
		||||
 | 
			
		||||
  // Force connection pool if there is one
 | 
			
		||||
  if(server.connectionPool) server.connectionPool.stop();
 | 
			
		||||
  // Set server state to connecting
 | 
			
		||||
  this._serverState = 'connecting';
 | 
			
		||||
 | 
			
		||||
  if(server.connectionPool != null) {
 | 
			
		||||
    // Remove all the listeners on the pool so it does not fire messages all over the place
 | 
			
		||||
    this.connectionPool.removeAllEventListeners();
 | 
			
		||||
    // Close the connection if it's open
 | 
			
		||||
    this.connectionPool.stop(true);    
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.connectionPool = new ConnectionPool(this.host, this.port, this.poolSize, dbInstance.bson, this.socketOptions);
 | 
			
		||||
  var connectionPool = this.connectionPool;
 | 
			
		||||
  // If ssl is not enabled don't wait between the pool connections
 | 
			
		||||
  if(this.ssl == null || !this.ssl) connectionPool._timeToWait = null;
 | 
			
		||||
  // Set logger on pool
 | 
			
		||||
  connectionPool.logger = this.logger;
 | 
			
		||||
  connectionPool.bson = dbInstance.bson;
 | 
			
		||||
 | 
			
		||||
  // Set basic parameters passed in
 | 
			
		||||
  var returnIsMasterResults = options.returnIsMasterResults == null ? false : options.returnIsMasterResults;
 | 
			
		||||
 | 
			
		||||
  // Create a default connect handler, overriden when using replicasets
 | 
			
		||||
  var connectCallback = function(_server) {
 | 
			
		||||
    return function(err, reply) {  
 | 
			
		||||
      // ensure no callbacks get called twice
 | 
			
		||||
      var internalCallback = callback;
 | 
			
		||||
      callback = null;
 | 
			
		||||
      
 | 
			
		||||
      // Assign the server
 | 
			
		||||
      _server = _server != null ? _server : server;
 | 
			
		||||
      
 | 
			
		||||
      // If something close down the connection and removed the callback before
 | 
			
		||||
      // proxy killed connection etc, ignore the erorr as close event was isssued
 | 
			
		||||
      if(err != null && internalCallback == null) return;
 | 
			
		||||
      // Internal callback
 | 
			
		||||
      if(err != null) return internalCallback(err, null, _server);
 | 
			
		||||
      if(reply == null || reply.documents == null) return internalCallback(utils.toError("server failed to respond", null, _server));
 | 
			
		||||
      _server.master = reply.documents[0].ismaster == 1 ? true : false;
 | 
			
		||||
      _server.connectionPool.setMaxBsonSize(reply.documents[0].maxBsonObjectSize);
 | 
			
		||||
      _server.connectionPool.setMaxMessageSizeBytes(reply.documents[0].maxMessageSizeBytes);
 | 
			
		||||
      _server.connectionPool.setMaxWriteBatchSize(reply.documents[0].maxWriteBatchSize);
 | 
			
		||||
      // Set server state to connEcted
 | 
			
		||||
      _server._serverState = 'connected';
 | 
			
		||||
      // Set server as connected
 | 
			
		||||
      _server.connected = true;
 | 
			
		||||
      // Save document returned so we can query it
 | 
			
		||||
      _server.isMasterDoc = reply.documents[0];
 | 
			
		||||
      
 | 
			
		||||
      if(self.emitOpen) {        
 | 
			
		||||
        _server._emitAcrossAllDbInstances(_server, eventReceiver, "open", null, returnIsMasterResults ? reply : null, null);        
 | 
			
		||||
        self.emitOpen = false;
 | 
			
		||||
      } else {
 | 
			
		||||
        _server._emitAcrossAllDbInstances(_server, eventReceiver, "reconnect", null, returnIsMasterResults ? reply : null, null);        
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Set server capabilities
 | 
			
		||||
      server.serverCapabilities = new ServerCapabilities(_server.isMasterDoc);      
 | 
			
		||||
 | 
			
		||||
      // Set server capabilities on all the connections
 | 
			
		||||
      var connections = connectionPool.getAllConnections();
 | 
			
		||||
      for(var i = 0; i < connections.length; i++) {
 | 
			
		||||
        connections[i].serverCapabilities = server.serverCapabilities;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // If we have it set to returnIsMasterResults
 | 
			
		||||
      if(returnIsMasterResults) {
 | 
			
		||||
        internalCallback(null, reply, _server);
 | 
			
		||||
      } else {
 | 
			
		||||
        internalCallback(null, dbInstance, _server);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  // Let's us override the main connect callback
 | 
			
		||||
  var connectHandler = options.connectHandler == null ? connectCallback(server) : options.connectHandler;
 | 
			
		||||
 | 
			
		||||
  // Set up on connect method
 | 
			
		||||
  connectionPool.on("poolReady", function() {
 | 
			
		||||
    // Create db command and Add the callback to the list of callbacks by the request id (mapping outgoing messages to correct callbacks)
 | 
			
		||||
    var db_command = DbCommand.NcreateIsMasterCommand(dbInstance, dbInstance.databaseName);
 | 
			
		||||
    // Check out a reader from the pool
 | 
			
		||||
    var connection = connectionPool.checkoutConnection();
 | 
			
		||||
    // Register handler for messages
 | 
			
		||||
    server._registerHandler(db_command, false, connection, connectHandler);
 | 
			
		||||
    // Write the command out
 | 
			
		||||
    connection.write(db_command);
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  // Set up item connection
 | 
			
		||||
  connectionPool.on("message", function(message) {
 | 
			
		||||
    // Attempt to parse the message
 | 
			
		||||
    try {
 | 
			
		||||
      // Create a new mongo reply
 | 
			
		||||
      var mongoReply = new MongoReply()
 | 
			
		||||
      // Parse the header
 | 
			
		||||
      mongoReply.parseHeader(message, connectionPool.bson)
 | 
			
		||||
 | 
			
		||||
      // If message size is not the same as the buffer size
 | 
			
		||||
      // something went terribly wrong somewhere
 | 
			
		||||
      if(mongoReply.messageLength != message.length) {
 | 
			
		||||
        // Emit the error
 | 
			
		||||
        if(eventReceiver.listeners("error") && eventReceiver.listeners("error").length > 0) eventReceiver.emit("error", new Error("bson length is different from message length"), server);
 | 
			
		||||
        // Remove all listeners
 | 
			
		||||
        server.removeAllListeners();
 | 
			
		||||
      } else {
 | 
			
		||||
        var startDate = new Date().getTime();
 | 
			
		||||
 | 
			
		||||
        // Callback instance
 | 
			
		||||
        var callbackInfo = server._findHandler(mongoReply.responseTo.toString());
 | 
			
		||||
        // Abort if not a valid callbackInfo, don't try to call it
 | 
			
		||||
        if(callbackInfo == null || callbackInfo.info == null) return;
 | 
			
		||||
 | 
			
		||||
        // The command executed another request, log the handler again under that request id
 | 
			
		||||
        if(mongoReply.requestId > 0 && mongoReply.cursorId.toString() != "0" 
 | 
			
		||||
          && callbackInfo && callbackInfo.info && callbackInfo.info.exhaust) {
 | 
			
		||||
            server._reRegisterHandler(mongoReply.requestId, callbackInfo);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Parse the body
 | 
			
		||||
        mongoReply.parseBody(message, connectionPool.bson, callbackInfo.info.raw, function(err) {
 | 
			
		||||
          if(err != null) {
 | 
			
		||||
            // If pool connection is already closed
 | 
			
		||||
            if(server._serverState === 'disconnected') return;
 | 
			
		||||
            // Set server state to disconnected
 | 
			
		||||
            server._serverState = 'disconnected';
 | 
			
		||||
            // Remove all listeners and close the connection pool
 | 
			
		||||
            server.removeAllListeners();
 | 
			
		||||
            connectionPool.stop(true);
 | 
			
		||||
 | 
			
		||||
            // If we have a callback return the error
 | 
			
		||||
            if(typeof callback === 'function') {
 | 
			
		||||
              // ensure no callbacks get called twice
 | 
			
		||||
              var internalCallback = callback;
 | 
			
		||||
              callback = null;
 | 
			
		||||
              // Perform callback
 | 
			
		||||
              internalCallback(err, null, server);
 | 
			
		||||
            } else if(server.isSetMember()) {
 | 
			
		||||
              if(server.listeners("parseError") && server.listeners("parseError").length > 0) server.emit("parseError", utils.toError(err), server);
 | 
			
		||||
            } else {
 | 
			
		||||
              if(eventReceiver.listeners("parseError") && eventReceiver.listeners("parseError").length > 0) eventReceiver.emit("parseError", utils.toError(err), server);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // If we are a single server connection fire errors correctly
 | 
			
		||||
            if(!server.isSetMember()) {
 | 
			
		||||
              // Fire all callback errors
 | 
			
		||||
              server.__executeAllCallbacksWithError(err);
 | 
			
		||||
              // Emit error
 | 
			
		||||
              server._emitAcrossAllDbInstances(server, eventReceiver, "parseError", server, null, true);
 | 
			
		||||
            }
 | 
			
		||||
            // Short cut
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          // Let's record the stats info if it's enabled
 | 
			
		||||
          if(server.recordQueryStats == true && server._state['runtimeStats'] != null
 | 
			
		||||
            && server._state.runtimeStats['queryStats'] instanceof RunningStats) {
 | 
			
		||||
            // Add data point to the running statistics object
 | 
			
		||||
            server._state.runtimeStats.queryStats.push(new Date().getTime() - callbackInfo.info.start);
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          // Dispatch the call
 | 
			
		||||
          server._callHandler(mongoReply.responseTo, mongoReply, null);
 | 
			
		||||
 | 
			
		||||
          // If we have an error about the server not being master or primary
 | 
			
		||||
          if((mongoReply.responseFlag & (1 << 1)) != 0
 | 
			
		||||
            && mongoReply.documents[0].code
 | 
			
		||||
            && mongoReply.documents[0].code == 13436) {
 | 
			
		||||
              server.close();
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
    } catch (err) {
 | 
			
		||||
      // Throw error in next tick
 | 
			
		||||
      processor(function() {
 | 
			
		||||
        throw err;
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // Handle timeout
 | 
			
		||||
  connectionPool.on("timeout", function(err) {
 | 
			
		||||
    // If pool connection is already closed
 | 
			
		||||
    if(server._serverState === 'disconnected' 
 | 
			
		||||
      || server._serverState === 'destroyed') return;
 | 
			
		||||
    // Set server state to disconnected
 | 
			
		||||
    server._serverState = 'disconnected';
 | 
			
		||||
    // If we have a callback return the error
 | 
			
		||||
    if(typeof callback === 'function') {
 | 
			
		||||
      // ensure no callbacks get called twice
 | 
			
		||||
      var internalCallback = callback;
 | 
			
		||||
      callback = null;
 | 
			
		||||
      // Perform callback
 | 
			
		||||
      internalCallback(err, null, server);
 | 
			
		||||
    } else if(server.isSetMember()) {
 | 
			
		||||
      if(server.listeners("timeout") && server.listeners("timeout").length > 0) server.emit("timeout", err, server);
 | 
			
		||||
    } else {
 | 
			
		||||
      if(eventReceiver.listeners("timeout") && eventReceiver.listeners("timeout").length > 0) eventReceiver.emit("timeout", err, server);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If we are a single server connection fire errors correctly
 | 
			
		||||
    if(!server.isSetMember()) {
 | 
			
		||||
      // Fire all callback errors
 | 
			
		||||
      server.__executeAllCallbacksWithError(err);
 | 
			
		||||
      // Emit error
 | 
			
		||||
      server._emitAcrossAllDbInstances(server, eventReceiver, "timeout", err, server, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If we have autoConnect enabled let's fire up an attempt to reconnect
 | 
			
		||||
    if(server.isAutoReconnect() 
 | 
			
		||||
      && !server.isSetMember()
 | 
			
		||||
      && (server._serverState != 'destroyed')
 | 
			
		||||
      && !server._reconnectInProgreess) {
 | 
			
		||||
      // Set the number of retries
 | 
			
		||||
      server._reconnect_retries = server.db.numberOfRetries;
 | 
			
		||||
      // Attempt reconnect
 | 
			
		||||
      server._reconnectInProgreess = true;
 | 
			
		||||
      setTimeout(__attemptReconnect(server), server.db.retryMiliSeconds);
 | 
			
		||||
    }    
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // Handle errors
 | 
			
		||||
  connectionPool.on("error", function(message, connection, error_options) {
 | 
			
		||||
    // If pool connection is already closed
 | 
			
		||||
    if(server._serverState === 'disconnected' 
 | 
			
		||||
      || server._serverState === 'destroyed') return;
 | 
			
		||||
    
 | 
			
		||||
    // Set server state to disconnected
 | 
			
		||||
    server._serverState = 'disconnected';
 | 
			
		||||
    // Error message
 | 
			
		||||
    var error_message = new Error(message && message.err ? message.err : message);
 | 
			
		||||
    // Error message coming from ssl
 | 
			
		||||
    if(error_options && error_options.ssl) error_message.ssl = true;
 | 
			
		||||
 | 
			
		||||
    // If we have a callback return the error
 | 
			
		||||
    if(typeof callback === 'function') {
 | 
			
		||||
      // ensure no callbacks get called twice
 | 
			
		||||
      var internalCallback = callback;
 | 
			
		||||
      callback = null;
 | 
			
		||||
      // Perform callback
 | 
			
		||||
      internalCallback(error_message, null, server);
 | 
			
		||||
    } else if(server.isSetMember()) {
 | 
			
		||||
      if(server.listeners("error") && server.listeners("error").length > 0) server.emit("error", error_message, server);
 | 
			
		||||
    } else {
 | 
			
		||||
      if(eventReceiver.listeners("error") && eventReceiver.listeners("error").length > 0) eventReceiver.emit("error", error_message, server);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If we are a single server connection fire errors correctly
 | 
			
		||||
    if(!server.isSetMember()) {
 | 
			
		||||
      // Fire all callback errors
 | 
			
		||||
      server.__executeAllCallbacksWithError(error_message);
 | 
			
		||||
      // Emit error
 | 
			
		||||
      server._emitAcrossAllDbInstances(server, eventReceiver, "error", error_message, server, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If we have autoConnect enabled let's fire up an attempt to reconnect
 | 
			
		||||
    if(server.isAutoReconnect() 
 | 
			
		||||
      && !server.isSetMember()
 | 
			
		||||
      && (server._serverState != 'destroyed')
 | 
			
		||||
      && !server._reconnectInProgreess) {
 | 
			
		||||
 | 
			
		||||
      // Set the number of retries
 | 
			
		||||
      server._reconnect_retries = server.db.numberOfRetries;
 | 
			
		||||
      // Attempt reconnect
 | 
			
		||||
      server._reconnectInProgreess = true;
 | 
			
		||||
      setTimeout(__attemptReconnect(server), server.db.retryMiliSeconds);
 | 
			
		||||
    }    
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // Handle close events
 | 
			
		||||
  connectionPool.on("close", function() {
 | 
			
		||||
    // If pool connection is already closed
 | 
			
		||||
    if(server._serverState === 'disconnected' 
 | 
			
		||||
      || server._serverState === 'destroyed') return;
 | 
			
		||||
    // Set server state to disconnected
 | 
			
		||||
    server._serverState = 'disconnected';
 | 
			
		||||
    // If we have a callback return the error
 | 
			
		||||
    if(typeof callback == 'function') {
 | 
			
		||||
      // ensure no callbacks get called twice
 | 
			
		||||
      var internalCallback = callback;
 | 
			
		||||
      callback = null;
 | 
			
		||||
      // Perform callback
 | 
			
		||||
      internalCallback(new Error("connection closed"), null, server);
 | 
			
		||||
    } else if(server.isSetMember()) {
 | 
			
		||||
      if(server.listeners("close") && server.listeners("close").length > 0) server.emit("close", new Error("connection closed"), server);
 | 
			
		||||
    } else {
 | 
			
		||||
      if(eventReceiver.listeners("close") && eventReceiver.listeners("close").length > 0) eventReceiver.emit("close", new Error("connection closed"), server);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If we are a single server connection fire errors correctly
 | 
			
		||||
    if(!server.isSetMember()) {
 | 
			
		||||
      // Fire all callback errors
 | 
			
		||||
      server.__executeAllCallbacksWithError(new Error("connection closed"));
 | 
			
		||||
      // Emit error
 | 
			
		||||
      server._emitAcrossAllDbInstances(server, eventReceiver, "close", server, null, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If we have autoConnect enabled let's fire up an attempt to reconnect
 | 
			
		||||
    if(server.isAutoReconnect() 
 | 
			
		||||
      && !server.isSetMember()
 | 
			
		||||
      && (server._serverState != 'destroyed')
 | 
			
		||||
      && !server._reconnectInProgreess) {
 | 
			
		||||
 | 
			
		||||
      // Set the number of retries
 | 
			
		||||
      server._reconnect_retries = server.db.numberOfRetries;  
 | 
			
		||||
      // Attempt reconnect
 | 
			
		||||
      server._reconnectInProgreess = true;
 | 
			
		||||
      setTimeout(__attemptReconnect(server), server.db.retryMiliSeconds);
 | 
			
		||||
    }    
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @ignore
 | 
			
		||||
   */
 | 
			
		||||
  var __attemptReconnect = function(server) {
 | 
			
		||||
    return function() {
 | 
			
		||||
      // Attempt reconnect
 | 
			
		||||
      server.connect(server.db, server.options, function(err, result) {
 | 
			
		||||
        server._reconnect_retries = server._reconnect_retries - 1;
 | 
			
		||||
 | 
			
		||||
        if(err) {
 | 
			
		||||
          // Retry
 | 
			
		||||
          if(server._reconnect_retries == 0 || server._serverState == 'destroyed') {
 | 
			
		||||
            server._serverState = 'connected';
 | 
			
		||||
            server._reconnectInProgreess = false
 | 
			
		||||
            // Fire all callback errors
 | 
			
		||||
            return server.__executeAllCallbacksWithError(new Error("failed to reconnect to server"));
 | 
			
		||||
          } else {
 | 
			
		||||
            return setTimeout(__attemptReconnect(server), server.db.retryMiliSeconds);
 | 
			
		||||
          }
 | 
			
		||||
        } else {
 | 
			
		||||
          // Set as authenticating (isConnected will be false)
 | 
			
		||||
          server._serverState = 'authenticating';
 | 
			
		||||
          // Apply any auths, we don't try to catch any errors here
 | 
			
		||||
          // as there are nowhere to simply propagate them to
 | 
			
		||||
          self._apply_auths(server.db, function(err, result) {            
 | 
			
		||||
            server._serverState = 'connected';
 | 
			
		||||
            server._reconnectInProgreess = false;
 | 
			
		||||
 | 
			
		||||
            // Execute any buffered reads and writes
 | 
			
		||||
            server._commandsStore.execute_queries();
 | 
			
		||||
            server._commandsStore.execute_writes();
 | 
			
		||||
            // Emit reconnect event
 | 
			
		||||
            server.emit('reconnect');
 | 
			
		||||
          });
 | 
			
		||||
        } 
 | 
			
		||||
      });      
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // If we have a parser error we are in an unknown state, close everything and emit
 | 
			
		||||
  // error
 | 
			
		||||
  connectionPool.on("parseError", function(err) {
 | 
			
		||||
    // If pool connection is already closed
 | 
			
		||||
    if(server._serverState === 'disconnected' 
 | 
			
		||||
      || server._serverState === 'destroyed') return;
 | 
			
		||||
    // Set server state to disconnected
 | 
			
		||||
    server._serverState = 'disconnected';
 | 
			
		||||
    // If we have a callback return the error
 | 
			
		||||
    if(typeof callback === 'function') {
 | 
			
		||||
      // ensure no callbacks get called twice
 | 
			
		||||
      var internalCallback = callback;
 | 
			
		||||
      callback = null;
 | 
			
		||||
      // Perform callback
 | 
			
		||||
      internalCallback(utils.toError(err), null, server);
 | 
			
		||||
    } else if(server.isSetMember()) {
 | 
			
		||||
      if(server.listeners("parseError") && server.listeners("parseError").length > 0) server.emit("parseError", utils.toError(err), server);
 | 
			
		||||
    } else {
 | 
			
		||||
      if(eventReceiver.listeners("parseError") && eventReceiver.listeners("parseError").length > 0) eventReceiver.emit("parseError", utils.toError(err), server);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If we are a single server connection fire errors correctly
 | 
			
		||||
    if(!server.isSetMember()) {
 | 
			
		||||
      // Fire all callback errors
 | 
			
		||||
      server.__executeAllCallbacksWithError(utils.toError(err));
 | 
			
		||||
      // Emit error
 | 
			
		||||
      server._emitAcrossAllDbInstances(server, eventReceiver, "parseError", server, null, true);
 | 
			
		||||
      // Emit close event
 | 
			
		||||
      server._emitAcrossAllDbInstances(server, eventReceiver, "close", new Error("connection closed"), null, true);
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // Boot up connection poole, pass in a locator of callbacks
 | 
			
		||||
  connectionPool.start();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Server.prototype.allRawConnections = function() {
 | 
			
		||||
  return this.connectionPool != null ? this.connectionPool.getAllConnections() : [];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if a writer can be provided
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
var canCheckoutWriter = function(self, read) {
 | 
			
		||||
  var error = null;
 | 
			
		||||
  // We cannot write to an arbiter or secondary server
 | 
			
		||||
  if(self.isMasterDoc && self.isMasterDoc['arbiterOnly'] == true) {
 | 
			
		||||
    error = new Error("Cannot write to an arbiter");
 | 
			
		||||
    error.code = -5000;
 | 
			
		||||
  } if(self.isMasterDoc && self.isMasterDoc['secondary'] == true) {
 | 
			
		||||
    error = new Error("Cannot write to a secondary");
 | 
			
		||||
    error.code = -5000;
 | 
			
		||||
  } else if(read == true && self._readPreference == ReadPreference.SECONDARY && self.isMasterDoc && self.isMasterDoc['ismaster'] == true) {
 | 
			
		||||
    error = new Error("Cannot read from primary when secondary only specified");
 | 
			
		||||
    error.code = -5000;
 | 
			
		||||
  } else if(!self.isMasterDoc) {
 | 
			
		||||
    error = new Error("Cannot determine state of server");
 | 
			
		||||
    error.code = -5000;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Return no error
 | 
			
		||||
  return error;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Server.prototype.checkoutWriter = function(read) {
 | 
			
		||||
  if(this._serverState == 'disconnected' || this._serverState == 'destroyed')
 | 
			
		||||
    return null;
 | 
			
		||||
  if(read == true) return this.connectionPool.checkoutConnection();
 | 
			
		||||
  // Check if are allowed to do a checkout (if we try to use an arbiter f.ex)
 | 
			
		||||
  var result = canCheckoutWriter(this, read);
 | 
			
		||||
  // If the result is null check out a writer
 | 
			
		||||
  if(result == null && this.connectionPool != null) {
 | 
			
		||||
    return this.connectionPool.checkoutConnection();
 | 
			
		||||
  } else if(result == null) {
 | 
			
		||||
    return null;
 | 
			
		||||
  } else {
 | 
			
		||||
    return result;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if a reader can be provided
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
var canCheckoutReader = function(self) {
 | 
			
		||||
  // We cannot write to an arbiter or secondary server
 | 
			
		||||
  if(self.isMasterDoc && self.isMasterDoc['arbiterOnly'] == true && self.isSetMember()) {
 | 
			
		||||
    return new Error("Cannot write to an arbiter");
 | 
			
		||||
  } else if(self._readPreference != null) {
 | 
			
		||||
    // If the read preference is Primary and the instance is not a master return an error
 | 
			
		||||
    if((self._readPreference == ReadPreference.PRIMARY) && self.isMasterDoc && self.isMasterDoc['ismaster'] != true) {
 | 
			
		||||
      return new Error("Read preference is Server.PRIMARY and server is not master");
 | 
			
		||||
    } else if(self._readPreference == ReadPreference.SECONDARY && self.isMasterDoc && self.isMasterDoc['ismaster'] == true) {
 | 
			
		||||
      return new Error("Cannot read from primary when secondary only specified");
 | 
			
		||||
    }
 | 
			
		||||
  } else if(!self.isMasterDoc) {
 | 
			
		||||
    return new Error("Cannot determine state of server");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Return no error
 | 
			
		||||
  return null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Server.prototype.checkoutReader = function(read) {
 | 
			
		||||
  if(this._serverState == 'disconnected' || this._serverState == 'destroyed')
 | 
			
		||||
    return null;
 | 
			
		||||
  // Check if are allowed to do a checkout (if we try to use an arbiter f.ex)
 | 
			
		||||
  var result = canCheckoutReader(this);
 | 
			
		||||
  // If the result is null check out a writer
 | 
			
		||||
  if(result == null && this.connectionPool != null) {
 | 
			
		||||
    return this.connectionPool.checkoutConnection();
 | 
			
		||||
  } else if(result == null) {
 | 
			
		||||
    return null;
 | 
			
		||||
  } else {
 | 
			
		||||
    return result;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Server.prototype.enableRecordQueryStats = function(enable) {
 | 
			
		||||
  this.recordQueryStats = enable;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Internal statistics object used for calculating average and standard devitation on
 | 
			
		||||
 * running queries
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
var RunningStats = function() {
 | 
			
		||||
  var self = this;
 | 
			
		||||
  this.m_n = 0;
 | 
			
		||||
  this.m_oldM = 0.0;
 | 
			
		||||
  this.m_oldS = 0.0;
 | 
			
		||||
  this.m_newM = 0.0;
 | 
			
		||||
  this.m_newS = 0.0;
 | 
			
		||||
 | 
			
		||||
  // Define getters
 | 
			
		||||
  Object.defineProperty(this, "numDataValues", { enumerable: true
 | 
			
		||||
    , get: function () { return this.m_n; }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  Object.defineProperty(this, "mean", { enumerable: true
 | 
			
		||||
    , get: function () { return (this.m_n > 0) ? this.m_newM : 0.0; }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  Object.defineProperty(this, "variance", { enumerable: true
 | 
			
		||||
    , get: function () { return ((this.m_n > 1) ? this.m_newS/(this.m_n - 1) : 0.0); }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  Object.defineProperty(this, "standardDeviation", { enumerable: true
 | 
			
		||||
    , get: function () { return Math.sqrt(this.variance); }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  Object.defineProperty(this, "sScore", { enumerable: true
 | 
			
		||||
    , get: function () {
 | 
			
		||||
      var bottom = this.mean + this.standardDeviation;
 | 
			
		||||
      if(bottom == 0) return 0;
 | 
			
		||||
      return ((2 * this.mean * this.standardDeviation)/(bottom));
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
RunningStats.prototype.push = function(x) {
 | 
			
		||||
  // Update the number of samples
 | 
			
		||||
  this.m_n = this.m_n + 1;
 | 
			
		||||
  
 | 
			
		||||
  // See Knuth TAOCP vol 2, 3rd edition, page 232
 | 
			
		||||
  if(this.m_n == 1) {
 | 
			
		||||
    this.m_oldM = this.m_newM = x;
 | 
			
		||||
    this.m_oldS = 0.0;
 | 
			
		||||
  } else {
 | 
			
		||||
    this.m_newM = this.m_oldM + (x - this.m_oldM) / this.m_n;
 | 
			
		||||
    this.m_newS = this.m_oldS + (x - this.m_oldM) * (x - this.m_newM);
 | 
			
		||||
    // set up for next iteration
 | 
			
		||||
    this.m_oldM = this.m_newM;
 | 
			
		||||
    this.m_oldS = this.m_newS;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Object.defineProperty(Server.prototype, "autoReconnect", { enumerable: true
 | 
			
		||||
  , get: function () {
 | 
			
		||||
      return this.options['auto_reconnect'] == null ? false : this.options['auto_reconnect'];
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Object.defineProperty(Server.prototype, "connection", { enumerable: true
 | 
			
		||||
  , get: function () {
 | 
			
		||||
      return this.internalConnection;
 | 
			
		||||
    }
 | 
			
		||||
  , set: function(connection) {
 | 
			
		||||
      this.internalConnection = connection;
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Object.defineProperty(Server.prototype, "master", { enumerable: true
 | 
			
		||||
  , get: function () {
 | 
			
		||||
      return this.internalMaster;
 | 
			
		||||
    }
 | 
			
		||||
  , set: function(value) {
 | 
			
		||||
      this.internalMaster = value;
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Object.defineProperty(Server.prototype, "primary", { enumerable: true
 | 
			
		||||
  , get: function () {
 | 
			
		||||
      return this;
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Getter for query Stats
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Object.defineProperty(Server.prototype, "queryStats", { enumerable: true
 | 
			
		||||
  , get: function () {
 | 
			
		||||
      return this._state.runtimeStats.queryStats;
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Object.defineProperty(Server.prototype, "runtimeStats", { enumerable: true
 | 
			
		||||
  , get: function () {
 | 
			
		||||
      return this._state.runtimeStats;
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get Read Preference method
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
Object.defineProperty(Server.prototype, "readPreference", { enumerable: true
 | 
			
		||||
  , get: function () {
 | 
			
		||||
      if(this._readPreference == null && this.readSecondary) {
 | 
			
		||||
        return Server.READ_SECONDARY;
 | 
			
		||||
      } else if(this._readPreference == null && !this.readSecondary) {
 | 
			
		||||
        return Server.READ_PRIMARY;
 | 
			
		||||
      } else {
 | 
			
		||||
        return this._readPreference;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
exports.Server = Server;
 | 
			
		||||
							
								
								
									
										57
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/server_capabilities.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										57
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/server_capabilities.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,57 @@
 | 
			
		||||
var ServerCapabilities = function(isMasterResult) {  
 | 
			
		||||
  // Capabilities
 | 
			
		||||
  var aggregationCursor = false;
 | 
			
		||||
  var writeCommands = false;
 | 
			
		||||
  var textSearch = false;
 | 
			
		||||
  var authCommands = false;
 | 
			
		||||
  var listCollections = false;
 | 
			
		||||
  var listIndexes = false;
 | 
			
		||||
  var maxNumberOfDocsInBatch = isMasterResult.maxWriteBatchSize || 1000;
 | 
			
		||||
 | 
			
		||||
  if(isMasterResult.minWireVersion >= 0) {
 | 
			
		||||
  	textSearch = true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(isMasterResult.maxWireVersion >= 1) {
 | 
			
		||||
  	aggregationCursor = true;
 | 
			
		||||
    authCommands = true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(isMasterResult.maxWireVersion >= 2) {
 | 
			
		||||
    writeCommands = true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(isMasterResult.maxWireVersion >= 3) {
 | 
			
		||||
    listCollections = true;
 | 
			
		||||
    listIndexes = true;
 | 
			
		||||
  }  
 | 
			
		||||
 | 
			
		||||
  // If no min or max wire version set to 0
 | 
			
		||||
  if(isMasterResult.minWireVersion == null) {
 | 
			
		||||
    isMasterResult.minWireVersion = 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(isMasterResult.maxWireVersion == null) {
 | 
			
		||||
    isMasterResult.maxWireVersion = 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Map up read only parameters
 | 
			
		||||
  setup_get_property(this, "hasAggregationCursor", aggregationCursor);
 | 
			
		||||
  setup_get_property(this, "hasWriteCommands", writeCommands);
 | 
			
		||||
  setup_get_property(this, "hasTextSearch", textSearch);
 | 
			
		||||
  setup_get_property(this, "hasAuthCommands", authCommands);
 | 
			
		||||
  setup_get_property(this, "hasListCollectionsCommand", listCollections);
 | 
			
		||||
  setup_get_property(this, "hasListIndexesCommand", listIndexes);
 | 
			
		||||
  setup_get_property(this, "minWireVersion", isMasterResult.minWireVersion);
 | 
			
		||||
  setup_get_property(this, "maxWireVersion", isMasterResult.maxWireVersion);
 | 
			
		||||
  setup_get_property(this, "maxNumberOfDocsInBatch", maxNumberOfDocsInBatch);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var setup_get_property = function(object, name, value) {
 | 
			
		||||
  Object.defineProperty(object, name, {
 | 
			
		||||
      enumerable: true
 | 
			
		||||
    , get: function () { return value; }
 | 
			
		||||
  });  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.ServerCapabilities = ServerCapabilities;
 | 
			
		||||
							
								
								
									
										265
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/url_parser.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										265
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/connection/url_parser.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,265 @@
 | 
			
		||||
var fs = require('fs'),
 | 
			
		||||
  ReadPreference = require('./read_preference').ReadPreference;
 | 
			
		||||
 | 
			
		||||
exports.parse = function(url, options) {
 | 
			
		||||
  // Ensure we have a default options object if none set
 | 
			
		||||
  options = options || {};
 | 
			
		||||
  // Variables
 | 
			
		||||
  var connection_part = '';
 | 
			
		||||
  var auth_part = '';
 | 
			
		||||
  var query_string_part = '';
 | 
			
		||||
  var dbName = 'admin';
 | 
			
		||||
 | 
			
		||||
  // Must start with mongodb
 | 
			
		||||
  if(url.indexOf("mongodb://") != 0)
 | 
			
		||||
    throw Error("URL must be in the format mongodb://user:pass@host:port/dbname");
 | 
			
		||||
  // If we have a ? mark cut the query elements off
 | 
			
		||||
  if(url.indexOf("?") != -1) {
 | 
			
		||||
    query_string_part = url.substr(url.indexOf("?") + 1);
 | 
			
		||||
    connection_part = url.substring("mongodb://".length, url.indexOf("?"))
 | 
			
		||||
  } else {
 | 
			
		||||
    connection_part = url.substring("mongodb://".length);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Check if we have auth params
 | 
			
		||||
  if(connection_part.indexOf("@") != -1) {
 | 
			
		||||
    auth_part = connection_part.split("@")[0];
 | 
			
		||||
    connection_part = connection_part.split("@")[1];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Check if the connection string has a db
 | 
			
		||||
  if(connection_part.indexOf(".sock") != -1) {
 | 
			
		||||
    if(connection_part.indexOf(".sock/") != -1) {
 | 
			
		||||
      dbName = connection_part.split(".sock/")[1];
 | 
			
		||||
      connection_part = connection_part.split("/", connection_part.indexOf(".sock") + ".sock".length);
 | 
			
		||||
    } 
 | 
			
		||||
  } else if(connection_part.indexOf("/") != -1) {
 | 
			
		||||
    dbName = connection_part.split("/")[1];
 | 
			
		||||
    connection_part = connection_part.split("/")[0];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Result object
 | 
			
		||||
  var object = {};
 | 
			
		||||
 | 
			
		||||
  // Pick apart the authentication part of the string
 | 
			
		||||
  var authPart = auth_part || '';
 | 
			
		||||
  var auth = authPart.split(':', 2);
 | 
			
		||||
  if(options['uri_decode_auth']){
 | 
			
		||||
    auth[0] = decodeURIComponent(auth[0]);
 | 
			
		||||
    if(auth[1]){
 | 
			
		||||
      auth[1] = decodeURIComponent(auth[1]);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Add auth to final object if we have 2 elements
 | 
			
		||||
  if(auth.length == 2) object.auth = {user: auth[0], password: auth[1]};
 | 
			
		||||
 | 
			
		||||
  // Variables used for temporary storage
 | 
			
		||||
  var hostPart;
 | 
			
		||||
  var urlOptions;
 | 
			
		||||
  var servers;
 | 
			
		||||
  var serverOptions = {socketOptions: {}};
 | 
			
		||||
  var dbOptions = {read_preference_tags: []};
 | 
			
		||||
  var replSetServersOptions = {socketOptions: {}};
 | 
			
		||||
  // Add server options to final object
 | 
			
		||||
  object.server_options = serverOptions;
 | 
			
		||||
  object.db_options = dbOptions;
 | 
			
		||||
  object.rs_options = replSetServersOptions;
 | 
			
		||||
  object.mongos_options = {};
 | 
			
		||||
 | 
			
		||||
  // Let's check if we are using a domain socket
 | 
			
		||||
  if(url.match(/\.sock/)) {
 | 
			
		||||
    // Split out the socket part
 | 
			
		||||
    var domainSocket = url.substring(
 | 
			
		||||
        url.indexOf("mongodb://") + "mongodb://".length
 | 
			
		||||
      , url.lastIndexOf(".sock") + ".sock".length);
 | 
			
		||||
    // Clean out any auth stuff if any
 | 
			
		||||
    if(domainSocket.indexOf("@") != -1) domainSocket = domainSocket.split("@")[1];
 | 
			
		||||
    servers = [{domain_socket: domainSocket}];
 | 
			
		||||
  } else {
 | 
			
		||||
    // Split up the db
 | 
			
		||||
    hostPart = connection_part;
 | 
			
		||||
    // Parse all server results
 | 
			
		||||
    servers = hostPart.split(',').map(function(h) {
 | 
			
		||||
      var _host, _port, ipv6match;
 | 
			
		||||
      //check if it matches [IPv6]:port, where the port number is optional
 | 
			
		||||
      if ((ipv6match = /\[([^\]]+)\](?:\:(.+))?/.exec(h))) {
 | 
			
		||||
        _host = ipv6match[1];
 | 
			
		||||
        _port = parseInt(ipv6match[2], 10) || 27017;
 | 
			
		||||
      } else {
 | 
			
		||||
        //otherwise assume it's IPv4, or plain hostname
 | 
			
		||||
        var hostPort = h.split(':', 2);
 | 
			
		||||
        _host = hostPort[0] || 'localhost';
 | 
			
		||||
        _port = hostPort[1] != null ? parseInt(hostPort[1], 10) : 27017;
 | 
			
		||||
        // Check for localhost?safe=true style case
 | 
			
		||||
        if(_host.indexOf("?") != -1) _host = _host.split(/\?/)[0];
 | 
			
		||||
      }
 | 
			
		||||
      // Return the mapped object
 | 
			
		||||
      return {host: _host, port: _port};
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Get the db name
 | 
			
		||||
  object.dbName = dbName || 'admin';
 | 
			
		||||
  // Split up all the options
 | 
			
		||||
  urlOptions = (query_string_part || '').split(/[&;]/);    
 | 
			
		||||
  // Ugh, we have to figure out which options go to which constructor manually.
 | 
			
		||||
  urlOptions.forEach(function(opt) {
 | 
			
		||||
    if(!opt) return;
 | 
			
		||||
    var splitOpt = opt.split('='), name = splitOpt[0], value = splitOpt[1];
 | 
			
		||||
    // Options implementations
 | 
			
		||||
    switch(name) {
 | 
			
		||||
      case 'slaveOk':
 | 
			
		||||
      case 'slave_ok':
 | 
			
		||||
        serverOptions.slave_ok = (value == 'true');
 | 
			
		||||
        dbOptions.slaveOk = (value == 'true');
 | 
			
		||||
        break;
 | 
			
		||||
      case 'maxPoolSize':
 | 
			
		||||
      case 'poolSize':
 | 
			
		||||
        serverOptions.poolSize = parseInt(value, 10);
 | 
			
		||||
        replSetServersOptions.poolSize = parseInt(value, 10);
 | 
			
		||||
        break;
 | 
			
		||||
      case 'autoReconnect':
 | 
			
		||||
      case 'auto_reconnect':
 | 
			
		||||
        serverOptions.auto_reconnect = (value == 'true');
 | 
			
		||||
        break;
 | 
			
		||||
      case 'minPoolSize':
 | 
			
		||||
        throw new Error("minPoolSize not supported");
 | 
			
		||||
      case 'maxIdleTimeMS':
 | 
			
		||||
        throw new Error("maxIdleTimeMS not supported");
 | 
			
		||||
      case 'waitQueueMultiple':
 | 
			
		||||
        throw new Error("waitQueueMultiple not supported");
 | 
			
		||||
      case 'waitQueueTimeoutMS':
 | 
			
		||||
        throw new Error("waitQueueTimeoutMS not supported");
 | 
			
		||||
      case 'uuidRepresentation':
 | 
			
		||||
        throw new Error("uuidRepresentation not supported");
 | 
			
		||||
      case 'ssl':
 | 
			
		||||
        if(value == 'prefer') {
 | 
			
		||||
          serverOptions.ssl = value;
 | 
			
		||||
          replSetServersOptions.ssl = value;
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
        serverOptions.ssl = (value == 'true');
 | 
			
		||||
        replSetServersOptions.ssl = (value == 'true');
 | 
			
		||||
        break;
 | 
			
		||||
      case 'replicaSet':
 | 
			
		||||
      case 'rs_name':
 | 
			
		||||
        replSetServersOptions.rs_name = value;
 | 
			
		||||
        break;
 | 
			
		||||
      case 'reconnectWait':
 | 
			
		||||
        replSetServersOptions.reconnectWait = parseInt(value, 10);
 | 
			
		||||
        break;
 | 
			
		||||
      case 'retries':
 | 
			
		||||
        replSetServersOptions.retries = parseInt(value, 10);
 | 
			
		||||
        break;
 | 
			
		||||
      case 'readSecondary':
 | 
			
		||||
      case 'read_secondary':
 | 
			
		||||
        replSetServersOptions.read_secondary = (value == 'true');
 | 
			
		||||
        break;
 | 
			
		||||
      case 'fsync':
 | 
			
		||||
        dbOptions.fsync = (value == 'true');
 | 
			
		||||
        break;
 | 
			
		||||
      case 'journal':
 | 
			
		||||
        dbOptions.journal = (value == 'true');
 | 
			
		||||
        break;
 | 
			
		||||
      case 'safe':
 | 
			
		||||
        dbOptions.safe = (value == 'true');
 | 
			
		||||
        break;
 | 
			
		||||
      case 'nativeParser':
 | 
			
		||||
      case 'native_parser':
 | 
			
		||||
        dbOptions.native_parser = (value == 'true');
 | 
			
		||||
        break;
 | 
			
		||||
      case 'connectTimeoutMS':
 | 
			
		||||
        serverOptions.socketOptions.connectTimeoutMS = parseInt(value, 10);
 | 
			
		||||
        replSetServersOptions.socketOptions.connectTimeoutMS = parseInt(value, 10);
 | 
			
		||||
        break;
 | 
			
		||||
      case 'socketTimeoutMS':
 | 
			
		||||
        serverOptions.socketOptions.socketTimeoutMS = parseInt(value, 10);
 | 
			
		||||
        replSetServersOptions.socketOptions.socketTimeoutMS = parseInt(value, 10);
 | 
			
		||||
        break;
 | 
			
		||||
      case 'w':
 | 
			
		||||
        dbOptions.w = parseInt(value, 10);
 | 
			
		||||
        if(isNaN(dbOptions.w)) dbOptions.w = value;
 | 
			
		||||
        break;
 | 
			
		||||
      case 'authSource':
 | 
			
		||||
        dbOptions.authSource = value;
 | 
			
		||||
        break;
 | 
			
		||||
      case 'gssapiServiceName':
 | 
			
		||||
        dbOptions.gssapiServiceName = value;
 | 
			
		||||
        break;
 | 
			
		||||
      case 'authMechanism':
 | 
			
		||||
        if(value == 'GSSAPI') {
 | 
			
		||||
          // If no password provided decode only the principal
 | 
			
		||||
          if(object.auth == null) {
 | 
			
		||||
            var urlDecodeAuthPart = decodeURIComponent(authPart);
 | 
			
		||||
            if(urlDecodeAuthPart.indexOf("@") == -1) throw new Error("GSSAPI requires a provided principal");
 | 
			
		||||
            object.auth = {user: urlDecodeAuthPart, password: null};
 | 
			
		||||
          } else {
 | 
			
		||||
            object.auth.user = decodeURIComponent(object.auth.user);
 | 
			
		||||
          }
 | 
			
		||||
        } else if(value == 'MONGODB-X509') {
 | 
			
		||||
          object.auth = {user: decodeURIComponent(authPart)};
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // Only support GSSAPI or MONGODB-CR for now
 | 
			
		||||
        if(value != 'GSSAPI' 
 | 
			
		||||
          && value != 'MONGODB-X509'
 | 
			
		||||
          && value != 'SCRAM-SHA-1'
 | 
			
		||||
          && value != 'MONGODB-CR'
 | 
			
		||||
          && value != 'PLAIN') 
 | 
			
		||||
            throw new Error("only GSSAPI, PLAIN, MONGODB-X509, SCRAM-SHA-1 or MONGODB-CR is supported by authMechanism");
 | 
			
		||||
        
 | 
			
		||||
        // Authentication mechanism
 | 
			
		||||
        dbOptions.authMechanism = value;
 | 
			
		||||
        break;
 | 
			
		||||
      case 'wtimeoutMS':
 | 
			
		||||
        dbOptions.wtimeout = parseInt(value, 10);
 | 
			
		||||
        break;
 | 
			
		||||
      case 'readPreference':
 | 
			
		||||
        if(!ReadPreference.isValid(value)) throw new Error("readPreference must be either primary/primaryPreferred/secondary/secondaryPreferred/nearest");
 | 
			
		||||
        dbOptions.read_preference = value;
 | 
			
		||||
        break;
 | 
			
		||||
      case 'readPreferenceTags':
 | 
			
		||||
        // Decode the value
 | 
			
		||||
        value = decodeURIComponent(value);
 | 
			
		||||
        // Contains the tag object
 | 
			
		||||
        var tagObject = {};
 | 
			
		||||
        if(value == null || value == '') {
 | 
			
		||||
          dbOptions.read_preference_tags.push(tagObject);
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Split up the tags
 | 
			
		||||
        var tags = value.split(/\,/);
 | 
			
		||||
        for(var i = 0; i < tags.length; i++) {
 | 
			
		||||
          var parts = tags[i].trim().split(/\:/);
 | 
			
		||||
          tagObject[parts[0]] = parts[1];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Set the preferences tags
 | 
			
		||||
        dbOptions.read_preference_tags.push(tagObject);
 | 
			
		||||
        break;
 | 
			
		||||
      default:
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // No tags: should be null (not [])
 | 
			
		||||
  if(dbOptions.read_preference_tags.length === 0) {
 | 
			
		||||
    dbOptions.read_preference_tags = null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Validate if there are an invalid write concern combinations
 | 
			
		||||
  if((dbOptions.w == -1 || dbOptions.w == 0) && (
 | 
			
		||||
      dbOptions.journal == true
 | 
			
		||||
      || dbOptions.fsync == true
 | 
			
		||||
      || dbOptions.safe == true)) throw new Error("w set to -1 or 0 cannot be combined with safe/w/journal/fsync")
 | 
			
		||||
 | 
			
		||||
  // If no read preference set it to primary
 | 
			
		||||
  if(!dbOptions.read_preference) dbOptions.read_preference = 'primary';
 | 
			
		||||
 | 
			
		||||
  // Add servers to result
 | 
			
		||||
  object.servers = servers;
 | 
			
		||||
  // Returned parsed object
 | 
			
		||||
  return object;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1058
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/cursor.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										1058
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/cursor.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										167
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/cursorstream.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										167
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/cursorstream.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,167 @@
 | 
			
		||||
var timers = require('timers');
 | 
			
		||||
 | 
			
		||||
// Set processor, setImmediate if 0.10 otherwise nextTick
 | 
			
		||||
var processor = require('./utils').processor();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Module dependecies.
 | 
			
		||||
 */
 | 
			
		||||
var Stream = require('stream').Stream;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * CursorStream
 | 
			
		||||
 *
 | 
			
		||||
 * Returns a stream interface for the **cursor**.
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **transform** {Function} function of type function(object) { return transformed }, allows for transformation of data before emitting.
 | 
			
		||||
 *
 | 
			
		||||
 * Events
 | 
			
		||||
 *  - **data** {function(item) {}} the data event triggers when a document is ready.
 | 
			
		||||
 *  - **error** {function(err) {}} the error event triggers if an error happens.
 | 
			
		||||
 *  - **close** {function() {}} the end event triggers when there is no more documents available.
 | 
			
		||||
 *
 | 
			
		||||
 * @class Represents a CursorStream.
 | 
			
		||||
 * @param {Cursor} cursor a cursor object that the stream wraps.
 | 
			
		||||
 * @return {Stream}
 | 
			
		||||
 */
 | 
			
		||||
function CursorStream(cursor, options) {
 | 
			
		||||
  if(!(this instanceof CursorStream)) return new CursorStream(cursor);
 | 
			
		||||
  options = options ? options : {};
 | 
			
		||||
 | 
			
		||||
  Stream.call(this);
 | 
			
		||||
 | 
			
		||||
  this.readable = true;
 | 
			
		||||
  this.paused = false;
 | 
			
		||||
  this._cursor = cursor;
 | 
			
		||||
  this._destroyed = null;
 | 
			
		||||
  this.options = options;
 | 
			
		||||
 | 
			
		||||
  // give time to hook up events
 | 
			
		||||
  var self = this;
 | 
			
		||||
  process.nextTick(function() {
 | 
			
		||||
    self._init();      
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Inherit from Stream
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
CursorStream.prototype.__proto__ = Stream.prototype;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Flag stating whether or not this stream is readable.
 | 
			
		||||
 */
 | 
			
		||||
CursorStream.prototype.readable;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Flag stating whether or not this stream is paused.
 | 
			
		||||
 */
 | 
			
		||||
CursorStream.prototype.paused;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Initialize the cursor.
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
CursorStream.prototype._init = function () {
 | 
			
		||||
  if (this._destroyed) return;
 | 
			
		||||
  this._next();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Pull the next document from the cursor.
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
CursorStream.prototype._next = function () {
 | 
			
		||||
  if(this.paused || this._destroyed) return;
 | 
			
		||||
 | 
			
		||||
  var self = this;
 | 
			
		||||
  // Get the next object
 | 
			
		||||
  processor(function() {
 | 
			
		||||
    if(self.paused || self._destroyed) return;
 | 
			
		||||
 | 
			
		||||
    self._cursor.nextObject(function (err, doc) {
 | 
			
		||||
      self._onNextObject(err, doc);
 | 
			
		||||
    });    
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handle each document as its returned from the cursor.
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
CursorStream.prototype._onNextObject = function (err, doc) {
 | 
			
		||||
  if(err) {
 | 
			
		||||
    this.destroy(err);
 | 
			
		||||
    return this.emit('end');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // when doc is null we hit the end of the cursor
 | 
			
		||||
  if(!doc && (this._cursor.state == 1 || this._cursor.state == 2)) {
 | 
			
		||||
    this.emit('end')
 | 
			
		||||
    return this.destroy();
 | 
			
		||||
  } else if(doc) {
 | 
			
		||||
    var data = typeof this.options.transform == 'function' ? this.options.transform(doc) : doc;
 | 
			
		||||
    this.emit('data', data);
 | 
			
		||||
    this._next();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Pauses the stream.
 | 
			
		||||
 *
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
CursorStream.prototype.pause = function () {
 | 
			
		||||
  this.paused = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Resumes the stream.
 | 
			
		||||
 *
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
CursorStream.prototype.resume = function () {
 | 
			
		||||
  var self = this;
 | 
			
		||||
 | 
			
		||||
  // Don't do anything if we are not paused
 | 
			
		||||
  if(!this.paused) return;
 | 
			
		||||
  if(!this._cursor.state == 3) return;
 | 
			
		||||
 | 
			
		||||
  process.nextTick(function() {
 | 
			
		||||
    self.paused = false;
 | 
			
		||||
    // Only trigger more fetching if the cursor is open
 | 
			
		||||
    self._next();
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Destroys the stream, closing the underlying
 | 
			
		||||
 * cursor. No more events will be emitted.
 | 
			
		||||
 *
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
CursorStream.prototype.destroy = function (err) {
 | 
			
		||||
  if (this._destroyed) return;
 | 
			
		||||
  this._destroyed = true;
 | 
			
		||||
  this.readable = false;
 | 
			
		||||
 | 
			
		||||
  this._cursor.close();
 | 
			
		||||
 | 
			
		||||
  if(err && this.listeners('error').length > 0) {
 | 
			
		||||
    return this.emit('error', err);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  this.emit('close');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO - maybe implement the raw option to pass binary?
 | 
			
		||||
//CursorStream.prototype.setEncoding = function () {
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
module.exports = exports = CursorStream;
 | 
			
		||||
							
								
								
									
										2182
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/db.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										2182
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/db.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										232
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/gridfs/chunk.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										232
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/gridfs/chunk.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,232 @@
 | 
			
		||||
var Binary = require('bson').Binary,
 | 
			
		||||
  ObjectID = require('bson').ObjectID;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class for representing a single chunk in GridFS.
 | 
			
		||||
 *
 | 
			
		||||
 * @class
 | 
			
		||||
 *
 | 
			
		||||
 * @param file {GridStore} The {@link GridStore} object holding this chunk.
 | 
			
		||||
 * @param mongoObject {object} The mongo object representation of this chunk.
 | 
			
		||||
 *
 | 
			
		||||
 * @throws Error when the type of data field for {@link mongoObject} is not
 | 
			
		||||
 *     supported. Currently supported types for data field are instances of
 | 
			
		||||
 *     {@link String}, {@link Array}, {@link Binary} and {@link Binary}
 | 
			
		||||
 *     from the bson module
 | 
			
		||||
 *
 | 
			
		||||
 * @see Chunk#buildMongoObject
 | 
			
		||||
 */
 | 
			
		||||
var Chunk = exports.Chunk = function(file, mongoObject, writeConcern) {
 | 
			
		||||
  if(!(this instanceof Chunk)) return new Chunk(file, mongoObject);
 | 
			
		||||
 | 
			
		||||
  this.file = file;
 | 
			
		||||
  var self = this;
 | 
			
		||||
  var mongoObjectFinal = mongoObject == null ? {} : mongoObject;
 | 
			
		||||
  this.writeConcern = writeConcern || {w:1};
 | 
			
		||||
  this.objectId = mongoObjectFinal._id == null ? new ObjectID() : mongoObjectFinal._id;
 | 
			
		||||
  this.chunkNumber = mongoObjectFinal.n == null ? 0 : mongoObjectFinal.n;
 | 
			
		||||
  this.data = new Binary();
 | 
			
		||||
 | 
			
		||||
  if(mongoObjectFinal.data == null) {
 | 
			
		||||
  } else if(typeof mongoObjectFinal.data == "string") {
 | 
			
		||||
    var buffer = new Buffer(mongoObjectFinal.data.length);
 | 
			
		||||
    buffer.write(mongoObjectFinal.data, 'binary', 0);
 | 
			
		||||
    this.data = new Binary(buffer);
 | 
			
		||||
  } else if(Array.isArray(mongoObjectFinal.data)) {
 | 
			
		||||
    var buffer = new Buffer(mongoObjectFinal.data.length);
 | 
			
		||||
    buffer.write(mongoObjectFinal.data.join(''), 'binary', 0);
 | 
			
		||||
    this.data = new Binary(buffer);
 | 
			
		||||
  } else if(mongoObjectFinal.data instanceof Binary || mongoObjectFinal.data._bsontype === 'Binary' || Object.prototype.toString.call(mongoObjectFinal.data) == "[object Binary]") {
 | 
			
		||||
    this.data = mongoObjectFinal.data;
 | 
			
		||||
  } else if(Buffer.isBuffer(mongoObjectFinal.data)) {
 | 
			
		||||
  } else {
 | 
			
		||||
    throw Error("Illegal chunk format");
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  // Update position
 | 
			
		||||
  this.internalPosition = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Writes a data to this object and advance the read/write head.
 | 
			
		||||
 *
 | 
			
		||||
 * @param data {string} the data to write 
 | 
			
		||||
 * @param callback {function(*, GridStore)} This will be called after executing
 | 
			
		||||
 *     this method. The first parameter will contain null and the second one
 | 
			
		||||
 *     will contain a reference to this object.
 | 
			
		||||
 */
 | 
			
		||||
Chunk.prototype.write = function(data, callback) {
 | 
			
		||||
  this.data.write(data, this.internalPosition);
 | 
			
		||||
  this.internalPosition = this.data.length();
 | 
			
		||||
  if(callback != null) return callback(null, this);
 | 
			
		||||
  return this;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Reads data and advances the read/write head.
 | 
			
		||||
 *
 | 
			
		||||
 * @param length {number} The length of data to read.
 | 
			
		||||
 *
 | 
			
		||||
 * @return {string} The data read if the given length will not exceed the end of
 | 
			
		||||
 *     the chunk. Returns an empty String otherwise.
 | 
			
		||||
 */
 | 
			
		||||
Chunk.prototype.read = function(length) {
 | 
			
		||||
  // Default to full read if no index defined
 | 
			
		||||
  length = length == null || length == 0 ? this.length() : length;
 | 
			
		||||
 | 
			
		||||
  if(this.length() - this.internalPosition + 1 >= length) {
 | 
			
		||||
    var data = this.data.read(this.internalPosition, length);
 | 
			
		||||
    this.internalPosition = this.internalPosition + length;
 | 
			
		||||
    return data;
 | 
			
		||||
  } else {
 | 
			
		||||
    return '';
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Chunk.prototype.readSlice = function(length) {
 | 
			
		||||
  if ((this.length() - this.internalPosition) >= length) {
 | 
			
		||||
    var data = null;
 | 
			
		||||
    if (this.data.buffer != null) { //Pure BSON
 | 
			
		||||
      data = this.data.buffer.slice(this.internalPosition, this.internalPosition + length);
 | 
			
		||||
    } else { //Native BSON
 | 
			
		||||
      data = new Buffer(length);
 | 
			
		||||
      length = this.data.readInto(data, this.internalPosition);
 | 
			
		||||
    }
 | 
			
		||||
    this.internalPosition = this.internalPosition + length;
 | 
			
		||||
    return data;
 | 
			
		||||
  } else {
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks if the read/write head is at the end.
 | 
			
		||||
 *
 | 
			
		||||
 * @return {boolean} Whether the read/write head has reached the end of this
 | 
			
		||||
 *     chunk.
 | 
			
		||||
 */
 | 
			
		||||
Chunk.prototype.eof = function() {
 | 
			
		||||
  return this.internalPosition == this.length() ? true : false;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Reads one character from the data of this chunk and advances the read/write
 | 
			
		||||
 * head.
 | 
			
		||||
 *
 | 
			
		||||
 * @return {string} a single character data read if the the read/write head is
 | 
			
		||||
 *     not at the end of the chunk. Returns an empty String otherwise.
 | 
			
		||||
 */
 | 
			
		||||
Chunk.prototype.getc = function() {
 | 
			
		||||
  return this.read(1);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Clears the contents of the data in this chunk and resets the read/write head
 | 
			
		||||
 * to the initial position.
 | 
			
		||||
 */
 | 
			
		||||
Chunk.prototype.rewind = function() {
 | 
			
		||||
  this.internalPosition = 0;
 | 
			
		||||
  this.data = new Binary();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Saves this chunk to the database. Also overwrites existing entries having the
 | 
			
		||||
 * same id as this chunk.
 | 
			
		||||
 *
 | 
			
		||||
 * @param callback {function(*, GridStore)} This will be called after executing
 | 
			
		||||
 *     this method. The first parameter will contain null and the second one
 | 
			
		||||
 *     will contain a reference to this object.
 | 
			
		||||
 */
 | 
			
		||||
Chunk.prototype.save = function(options, callback) {
 | 
			
		||||
  var self = this;
 | 
			
		||||
  if(typeof options == 'function') {
 | 
			
		||||
    callback = options;
 | 
			
		||||
    options = {};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  self.file.chunkCollection(function(err, collection) {
 | 
			
		||||
    if(err) return callback(err);
 | 
			
		||||
 | 
			
		||||
    // Merge the options
 | 
			
		||||
    var writeOptions = {};
 | 
			
		||||
    for(var name in options) writeOptions[name] = options[name];
 | 
			
		||||
    for(var name in self.writeConcern) writeOptions[name] = self.writeConcern[name];    
 | 
			
		||||
 | 
			
		||||
    // collection.remove({'_id':self.objectId}, self.writeConcern, function(err, result) {
 | 
			
		||||
    collection.remove({'_id':self.objectId}, writeOptions, function(err, result) {
 | 
			
		||||
      if(err) return callback(err);
 | 
			
		||||
 | 
			
		||||
      if(self.data.length() > 0) {
 | 
			
		||||
        self.buildMongoObject(function(mongoObject) {
 | 
			
		||||
          var options = {forceServerObjectId:true};
 | 
			
		||||
          for(var name in self.writeConcern) {
 | 
			
		||||
            options[name] = self.writeConcern[name];
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          collection.insert(mongoObject, writeOptions, function(err, collection) {
 | 
			
		||||
            callback(err, self);
 | 
			
		||||
          });
 | 
			
		||||
        });
 | 
			
		||||
      } else {
 | 
			
		||||
        callback(null, self);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Creates a mongoDB object representation of this chunk.
 | 
			
		||||
 *
 | 
			
		||||
 * @param callback {function(Object)} This will be called after executing this 
 | 
			
		||||
 *     method. The object will be passed to the first parameter and will have
 | 
			
		||||
 *     the structure:
 | 
			
		||||
 *        
 | 
			
		||||
 *        <pre><code>
 | 
			
		||||
 *        {
 | 
			
		||||
 *          '_id' : , // {number} id for this chunk
 | 
			
		||||
 *          'files_id' : , // {number} foreign key to the file collection
 | 
			
		||||
 *          'n' : , // {number} chunk number
 | 
			
		||||
 *          'data' : , // {bson#Binary} the chunk data itself
 | 
			
		||||
 *        }
 | 
			
		||||
 *        </code></pre>
 | 
			
		||||
 *
 | 
			
		||||
 * @see <a href="http://www.mongodb.org/display/DOCS/GridFS+Specification#GridFSSpecification-{{chunks}}">MongoDB GridFS Chunk Object Structure</a>
 | 
			
		||||
 */
 | 
			
		||||
Chunk.prototype.buildMongoObject = function(callback) {
 | 
			
		||||
  var mongoObject = {
 | 
			
		||||
    'files_id': this.file.fileId,
 | 
			
		||||
    'n': this.chunkNumber,
 | 
			
		||||
    'data': this.data};
 | 
			
		||||
  // If we are saving using a specific ObjectId
 | 
			
		||||
  if(this.objectId != null) mongoObject._id = this.objectId;
 | 
			
		||||
 | 
			
		||||
  callback(mongoObject);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @return {number} the length of the data
 | 
			
		||||
 */
 | 
			
		||||
Chunk.prototype.length = function() {
 | 
			
		||||
  return this.data.length();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The position of the read/write head
 | 
			
		||||
 * @name position
 | 
			
		||||
 * @lends Chunk#
 | 
			
		||||
 * @field
 | 
			
		||||
 */
 | 
			
		||||
Object.defineProperty(Chunk.prototype, "position", { enumerable: true
 | 
			
		||||
  , get: function () {
 | 
			
		||||
      return this.internalPosition;
 | 
			
		||||
    }
 | 
			
		||||
  , set: function(value) {
 | 
			
		||||
      this.internalPosition = value;
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The default chunk size
 | 
			
		||||
 * @constant
 | 
			
		||||
 */
 | 
			
		||||
Chunk.DEFAULT_CHUNK_SIZE = 1024 * 255;
 | 
			
		||||
							
								
								
									
										104
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/gridfs/grid.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										104
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/gridfs/grid.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,104 @@
 | 
			
		||||
var GridStore = require('./gridstore').GridStore,
 | 
			
		||||
  ObjectID = require('bson').ObjectID;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A class representation of a simple Grid interface.
 | 
			
		||||
 *
 | 
			
		||||
 * @class Represents the Grid.
 | 
			
		||||
 * @param {Db} db A database instance to interact with.
 | 
			
		||||
 * @param {String} [fsName] optional different root collection for GridFS.
 | 
			
		||||
 * @return {Grid}
 | 
			
		||||
 */
 | 
			
		||||
function Grid(db, fsName) {
 | 
			
		||||
 | 
			
		||||
  if(!(this instanceof Grid)) return new Grid(db, fsName);
 | 
			
		||||
 | 
			
		||||
  this.db = db;
 | 
			
		||||
  this.fsName = fsName == null ? GridStore.DEFAULT_ROOT_COLLECTION : fsName;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Puts binary data to the grid
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **_id** {Any}, unique id for this file
 | 
			
		||||
 *  - **filename** {String}, name for this file.
 | 
			
		||||
 *  - **root** {String}, root collection to use. Defaults to **{GridStore.DEFAULT_ROOT_COLLECTION}**.
 | 
			
		||||
 *  - **content_type** {String}, mime type of the file. Defaults to **{GridStore.DEFAULT_CONTENT_TYPE}**.
 | 
			
		||||
 *  - **chunk_size** {Number}, size for the chunk. Defaults to **{Chunk.DEFAULT_CHUNK_SIZE}**.
 | 
			
		||||
 *  - **metadata** {Object}, arbitrary data the user wants to store.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Buffer} data buffer with Binary Data.
 | 
			
		||||
 * @param {Object} [options] the options for the files.
 | 
			
		||||
 * @param {Function} callback this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Grid.prototype.put = function(data, options, callback) {
 | 
			
		||||
  var self = this;
 | 
			
		||||
  var args = Array.prototype.slice.call(arguments, 1);
 | 
			
		||||
  callback = args.pop();
 | 
			
		||||
  options = args.length ? args.shift() : {};
 | 
			
		||||
  // If root is not defined add our default one
 | 
			
		||||
  options['root'] = options['root'] == null ? this.fsName : options['root'];
 | 
			
		||||
 | 
			
		||||
  // Return if we don't have a buffer object as data
 | 
			
		||||
  if(!(Buffer.isBuffer(data))) return callback(new Error("Data object must be a buffer object"), null);
 | 
			
		||||
  // Get filename if we are using it
 | 
			
		||||
  var filename = options['filename'] || null;
 | 
			
		||||
  // Get id if we are using it
 | 
			
		||||
  var id = options['_id'] || null;
 | 
			
		||||
  // Create gridstore
 | 
			
		||||
  var gridStore = new GridStore(this.db, id, filename, "w", options);
 | 
			
		||||
  gridStore.open(function(err, gridStore) {
 | 
			
		||||
    if(err) return callback(err, null);
 | 
			
		||||
 | 
			
		||||
    gridStore.write(data, function(err, result) {
 | 
			
		||||
      if(err) return callback(err, null);
 | 
			
		||||
 | 
			
		||||
      gridStore.close(function(err, result) {
 | 
			
		||||
        if(err) return callback(err, null);
 | 
			
		||||
        callback(null, result);
 | 
			
		||||
      })
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get binary data to the grid
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Any} id for file.
 | 
			
		||||
 * @param {Function} callback this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Grid.prototype.get = function(id, callback) {
 | 
			
		||||
  // Create gridstore
 | 
			
		||||
  var gridStore = new GridStore(this.db, id, null, "r", {root:this.fsName});
 | 
			
		||||
  gridStore.open(function(err, gridStore) {
 | 
			
		||||
    if(err) return callback(err, null);
 | 
			
		||||
 | 
			
		||||
    // Return the data
 | 
			
		||||
    gridStore.read(function(err, data) {
 | 
			
		||||
      return callback(err, data)
 | 
			
		||||
    });
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Delete file from grid
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Any} id for file.
 | 
			
		||||
 * @param {Function} callback this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
Grid.prototype.delete = function(id, callback) {
 | 
			
		||||
  // Create gridstore
 | 
			
		||||
  GridStore.unlink(this.db, id, {root:this.fsName}, function(err, result) {
 | 
			
		||||
    if(err) return callback(err, false);
 | 
			
		||||
    return callback(null, true);
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.Grid = Grid;
 | 
			
		||||
							
								
								
									
										1570
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/gridfs/gridstore.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										1570
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/gridfs/gridstore.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										206
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/gridfs/readstream.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										206
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/gridfs/readstream.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,206 @@
 | 
			
		||||
var Stream = require('stream').Stream,
 | 
			
		||||
  timers = require('timers'),
 | 
			
		||||
  util = require('util');
 | 
			
		||||
 | 
			
		||||
// Set processor, setImmediate if 0.10 otherwise nextTick
 | 
			
		||||
var processor = require('../utils').processor();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ReadStream
 | 
			
		||||
 *
 | 
			
		||||
 * Returns a stream interface for the **file**.
 | 
			
		||||
 *
 | 
			
		||||
 * Events
 | 
			
		||||
 *  - **data** {function(item) {}} the data event triggers when a document is ready.
 | 
			
		||||
 *  - **end** {function() {}} the end event triggers when there is no more documents available.
 | 
			
		||||
 *  - **close** {function() {}} the close event triggers when the stream is closed.
 | 
			
		||||
 *  - **error** {function(err) {}} the error event triggers if an error happens.
 | 
			
		||||
 *
 | 
			
		||||
 * @class Represents a GridFS File Stream.
 | 
			
		||||
 * @param {Boolean} autoclose automatically close file when the stream reaches the end.
 | 
			
		||||
 * @param {GridStore} cursor a cursor object that the stream wraps.
 | 
			
		||||
 * @return {ReadStream}
 | 
			
		||||
 */
 | 
			
		||||
function ReadStream(autoclose, gstore) {
 | 
			
		||||
  if (!(this instanceof ReadStream)) return new ReadStream(autoclose, gstore);
 | 
			
		||||
  Stream.call(this);
 | 
			
		||||
 | 
			
		||||
  this.autoclose = !!autoclose;
 | 
			
		||||
  this.gstore = gstore;
 | 
			
		||||
 | 
			
		||||
  this.finalLength = gstore.length - gstore.position;
 | 
			
		||||
  this.completedLength = 0;
 | 
			
		||||
  this.currentChunkNumber = gstore.currentChunk.chunkNumber;
 | 
			
		||||
 | 
			
		||||
  this.paused = false;
 | 
			
		||||
  this.readable = true;
 | 
			
		||||
  this.pendingChunk = null;
 | 
			
		||||
  this.executing = false;  
 | 
			
		||||
  this.destroyed = false;
 | 
			
		||||
 | 
			
		||||
  // Calculate the number of chunks
 | 
			
		||||
  this.numberOfChunks = Math.ceil(gstore.length/gstore.chunkSize);
 | 
			
		||||
 | 
			
		||||
  // This seek start position inside the current chunk
 | 
			
		||||
  this.seekStartPosition = gstore.position - (this.currentChunkNumber * gstore.chunkSize);
 | 
			
		||||
  
 | 
			
		||||
  var self = this;
 | 
			
		||||
  processor(function() {
 | 
			
		||||
    self._execute();
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Inherit from Stream
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
ReadStream.prototype.__proto__ = Stream.prototype;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Flag stating whether or not this stream is readable.
 | 
			
		||||
 */
 | 
			
		||||
ReadStream.prototype.readable;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Flag stating whether or not this stream is paused.
 | 
			
		||||
 */
 | 
			
		||||
ReadStream.prototype.paused;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
ReadStream.prototype._execute = function() {
 | 
			
		||||
  if(this.paused === true || this.readable === false) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var gstore = this.gstore;
 | 
			
		||||
  var self = this;
 | 
			
		||||
  // Set that we are executing
 | 
			
		||||
  this.executing = true;
 | 
			
		||||
 | 
			
		||||
  var last = false;
 | 
			
		||||
  var toRead = 0;
 | 
			
		||||
 | 
			
		||||
  if(gstore.currentChunk.chunkNumber >= (this.numberOfChunks - 1)) {
 | 
			
		||||
    self.executing = false;    
 | 
			
		||||
    last = true;    
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Data setup
 | 
			
		||||
  var data = null;
 | 
			
		||||
 | 
			
		||||
  // Read a slice (with seek set if none)
 | 
			
		||||
  if(this.seekStartPosition > 0 && (gstore.currentChunk.length() - this.seekStartPosition) > 0) {
 | 
			
		||||
    data = gstore.currentChunk.readSlice(gstore.currentChunk.length() - this.seekStartPosition);
 | 
			
		||||
    this.seekStartPosition = 0;
 | 
			
		||||
  } else {
 | 
			
		||||
    data = gstore.currentChunk.readSlice(gstore.currentChunk.length());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var processNext = function() {
 | 
			
		||||
    if(last === true) {
 | 
			
		||||
      self.readable = false;
 | 
			
		||||
      self.emit("end");
 | 
			
		||||
      
 | 
			
		||||
      if(self.autoclose === true) {
 | 
			
		||||
        if(gstore.mode[0] == "w") {
 | 
			
		||||
          gstore.close(function(err, doc) {
 | 
			
		||||
            if (err) {
 | 
			
		||||
              self.emit("error", err);
 | 
			
		||||
              return;
 | 
			
		||||
            }
 | 
			
		||||
            self.readable = false;  
 | 
			
		||||
            self.destroyed = true;        
 | 
			
		||||
            self.emit("close", doc);
 | 
			
		||||
          });
 | 
			
		||||
        } else {
 | 
			
		||||
          self.readable = false;
 | 
			
		||||
          self.destroyed = true;        
 | 
			
		||||
          self.emit("close");
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      gstore._nthChunk(gstore.currentChunk.chunkNumber + 1, function(err, chunk) {
 | 
			
		||||
        if(err) {
 | 
			
		||||
          self.readable = false;
 | 
			
		||||
          if(self.listeners("error").length > 0)
 | 
			
		||||
            self.emit("error", err);
 | 
			
		||||
          self.executing = false;
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        self.pendingChunk = chunk;
 | 
			
		||||
        if(self.paused === true) {
 | 
			
		||||
          self.executing = false;
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        gstore.currentChunk = self.pendingChunk;
 | 
			
		||||
        self._execute();        
 | 
			
		||||
      });
 | 
			
		||||
    }    
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Return the data
 | 
			
		||||
  if(data != null && gstore.currentChunk.chunkNumber == self.currentChunkNumber) {
 | 
			
		||||
    self.currentChunkNumber = self.currentChunkNumber + 1;
 | 
			
		||||
    self.completedLength += data.length;
 | 
			
		||||
    self.pendingChunk = null;
 | 
			
		||||
    // Send the data
 | 
			
		||||
    process.nextTick(function() {
 | 
			
		||||
      self.emit("data", data); 
 | 
			
		||||
      processNext();           
 | 
			
		||||
    })
 | 
			
		||||
  } else {
 | 
			
		||||
    processNext();
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Pauses this stream, then no farther events will be fired.
 | 
			
		||||
 *
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
ReadStream.prototype.pause = function() {
 | 
			
		||||
  if(!this.executing) {
 | 
			
		||||
    this.paused = true;    
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Destroys the stream, then no farther events will be fired.
 | 
			
		||||
 *
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
ReadStream.prototype.destroy = function() {
 | 
			
		||||
  if(this.destroyed) return;
 | 
			
		||||
  this.destroyed = true;
 | 
			
		||||
  this.readable = false;
 | 
			
		||||
  // Emit close event
 | 
			
		||||
  this.emit("close");
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Resumes this stream.
 | 
			
		||||
 *
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
ReadStream.prototype.resume = function() {
 | 
			
		||||
  if(this.paused === false || !this.readable) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
    
 | 
			
		||||
  this.paused = false;
 | 
			
		||||
  var self = this;
 | 
			
		||||
  processor(function() {
 | 
			
		||||
    self._execute();
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
exports.ReadStream = ReadStream;
 | 
			
		||||
							
								
								
									
										62
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										62
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
try {
 | 
			
		||||
  exports.BSONPure = require('bson').BSONPure;
 | 
			
		||||
  exports.BSONNative = require('bson').BSONNative;
 | 
			
		||||
} catch(err) {
 | 
			
		||||
  // do nothing
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// export the driver version
 | 
			
		||||
exports.version = require('../../package').version;
 | 
			
		||||
 | 
			
		||||
[ 'commands/base_command'
 | 
			
		||||
  , 'admin'
 | 
			
		||||
  , 'collection'
 | 
			
		||||
  , 'connection/read_preference'
 | 
			
		||||
  , 'connection/connection'
 | 
			
		||||
  , 'connection/server'
 | 
			
		||||
  , 'connection/mongos'
 | 
			
		||||
  , 'connection/repl_set/repl_set'
 | 
			
		||||
  , 'mongo_client'
 | 
			
		||||
  , 'cursor'
 | 
			
		||||
  , 'db'
 | 
			
		||||
  , 'mongo_client'
 | 
			
		||||
  , 'gridfs/grid'
 | 
			
		||||
  ,	'gridfs/chunk'
 | 
			
		||||
  , 'gridfs/gridstore'].forEach(function (path) {
 | 
			
		||||
  	var module = require('./' + path);
 | 
			
		||||
  	for (var i in module) {
 | 
			
		||||
  		exports[i] = module[i];
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// backwards compat
 | 
			
		||||
exports.ReplSetServers = exports.ReplSet;
 | 
			
		||||
// Add BSON Classes
 | 
			
		||||
exports.Binary = require('bson').Binary;
 | 
			
		||||
exports.Code = require('bson').Code;
 | 
			
		||||
exports.DBRef = require('bson').DBRef;
 | 
			
		||||
exports.Double = require('bson').Double;
 | 
			
		||||
exports.Long = require('bson').Long;
 | 
			
		||||
exports.MinKey = require('bson').MinKey;
 | 
			
		||||
exports.MaxKey = require('bson').MaxKey;
 | 
			
		||||
exports.ObjectID = require('bson').ObjectID;
 | 
			
		||||
exports.Symbol = require('bson').Symbol;
 | 
			
		||||
exports.Timestamp = require('bson').Timestamp;  
 | 
			
		||||
// Add BSON Parser
 | 
			
		||||
exports.BSON = require('bson').BSONPure.BSON;
 | 
			
		||||
 | 
			
		||||
// Set up the connect function
 | 
			
		||||
var connect = exports.Db.connect;
 | 
			
		||||
 | 
			
		||||
// Add the pure and native backward compatible functions
 | 
			
		||||
exports.pure = exports.native = function() {
 | 
			
		||||
  return connect;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Map all values to the exports value
 | 
			
		||||
for(var name in exports) {
 | 
			
		||||
  connect[name] = exports[name];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Set our exports to be the connect function
 | 
			
		||||
module.exports = connect;
 | 
			
		||||
							
								
								
									
										482
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/mongo_client.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										482
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/mongo_client.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,482 @@
 | 
			
		||||
var Db = require('./db').Db
 | 
			
		||||
  , Server = require('./connection/server').Server
 | 
			
		||||
  , Mongos = require('./connection/mongos').Mongos
 | 
			
		||||
  , ReplSet = require('./connection/repl_set/repl_set').ReplSet
 | 
			
		||||
  , ReadPreference = require('./connection/read_preference').ReadPreference
 | 
			
		||||
  , inherits = require('util').inherits
 | 
			
		||||
  , EventEmitter = require('events').EventEmitter
 | 
			
		||||
  , parse = require('./connection/url_parser').parse;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create a new MongoClient instance.
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write
 | 
			
		||||
 *  - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option)
 | 
			
		||||
 *  - **fsync**, (Boolean, default:false) write waits for fsync before returning, from MongoDB 2.6 on, fsync cannot be combined with journal
 | 
			
		||||
 *  - **j**, (Boolean, default:false) write waits for journal sync before returning
 | 
			
		||||
 *  - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
 | 
			
		||||
 *  - **native_parser** {Boolean, default:false}, use c++ bson parser.
 | 
			
		||||
 *  - **forceServerObjectId** {Boolean, default:false}, force server to create _id fields instead of client.
 | 
			
		||||
 *  - **pkFactory** {Object}, object overriding the basic ObjectID primary key generation.
 | 
			
		||||
 *  - **serializeFunctions** {Boolean, default:false}, serialize functions.
 | 
			
		||||
 *  - **raw** {Boolean, default:false}, peform operations using raw bson buffers.
 | 
			
		||||
 *  - **recordQueryStats** {Boolean, default:false}, record query statistics during execution.
 | 
			
		||||
 *  - **retryMiliSeconds** {Number, default:5000}, number of miliseconds between retries.
 | 
			
		||||
 *  - **numberOfRetries** {Number, default:5}, number of retries off connection.
 | 
			
		||||
 *  - **bufferMaxEntries** {Boolean, default: -1}, sets a cap on how many operations the driver will buffer up before giving up on getting a working connection, default is -1 which is unlimited
 | 
			
		||||
 *
 | 
			
		||||
 * @class Represents a MongoClient
 | 
			
		||||
 * @param {Object} serverConfig server config object.
 | 
			
		||||
 * @param {Object} [options] additional options for the collection.
 | 
			
		||||
 */
 | 
			
		||||
function MongoClient(serverConfig, options) {
 | 
			
		||||
  if(serverConfig != null) {
 | 
			
		||||
    options = options ? options : {};
 | 
			
		||||
    // If no write concern is set set the default to w:1
 | 
			
		||||
    if('w' in options === false) {
 | 
			
		||||
      options.w = 1;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // The internal db instance we are wrapping
 | 
			
		||||
    this._db = new Db('test', serverConfig, options);    
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @ignore
 | 
			
		||||
 */
 | 
			
		||||
inherits(MongoClient, EventEmitter);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Connect to MongoDB using a url as documented at
 | 
			
		||||
 *
 | 
			
		||||
 *  docs.mongodb.org/manual/reference/connection-string/
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **uri_decode_auth** {Boolean, default:false} uri decode the user name and password for authentication
 | 
			
		||||
 *  - **db** {Object, default: null} a hash off options to set on the db object, see **Db constructor**
 | 
			
		||||
 *  - **server** {Object, default: null} a hash off options to set on the server objects, see **Server** constructor**
 | 
			
		||||
 *  - **replSet** {Object, default: null} a hash off options to set on the replSet object, see **ReplSet** constructor**
 | 
			
		||||
 *  - **mongos** {Object, default: null} a hash off options to set on the mongos object, see **Mongos** constructor**
 | 
			
		||||
 *
 | 
			
		||||
 * @param {String} url connection url for MongoDB.
 | 
			
		||||
 * @param {Object} [options] optional options for insert command
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the initialized db object or null if an error occured.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
MongoClient.prototype.connect = function(url, options, callback) {
 | 
			
		||||
  var self = this;
 | 
			
		||||
 | 
			
		||||
  if(typeof options == 'function') {
 | 
			
		||||
    callback = options;
 | 
			
		||||
    options = {};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  MongoClient.connect(url, options, function(err, db) {
 | 
			
		||||
    if(err) return callback(err, db);
 | 
			
		||||
    // Store internal db instance reference
 | 
			
		||||
    self._db = db;
 | 
			
		||||
    // Emit open and perform callback
 | 
			
		||||
    self.emit("open", err, db);
 | 
			
		||||
    callback(err, db);
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Initialize the database connection.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the connected mongoclient or null if an error occured.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
MongoClient.prototype.open = function(callback) {
 | 
			
		||||
  // Self reference
 | 
			
		||||
  var self = this;
 | 
			
		||||
  // Open the db
 | 
			
		||||
  this._db.open(function(err, db) {
 | 
			
		||||
    if(err) return callback(err, null);
 | 
			
		||||
    // Emit open event
 | 
			
		||||
    self.emit("open", err, db);
 | 
			
		||||
    // Callback
 | 
			
		||||
    callback(null, self);
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Close the current db connection, including all the child db instances. Emits close event and calls optional callback.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from the close method or null if an error occured.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
MongoClient.prototype.close = function(callback) {
 | 
			
		||||
  this._db.close(callback);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create a new Db instance sharing the current socket connections.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {String} dbName the name of the database we want to use.
 | 
			
		||||
 * @return {Db} a db instance using the new database.
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
MongoClient.prototype.db = function(dbName) {
 | 
			
		||||
  return this._db.db(dbName);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Connect to MongoDB using a url as documented at
 | 
			
		||||
 *
 | 
			
		||||
 *  docs.mongodb.org/manual/reference/connection-string/
 | 
			
		||||
 *
 | 
			
		||||
 * Options
 | 
			
		||||
 *  - **uri_decode_auth** {Boolean, default:false} uri decode the user name and password for authentication
 | 
			
		||||
 *  - **db** {Object, default: null} a hash off options to set on the db object, see **Db constructor**
 | 
			
		||||
 *  - **server** {Object, default: null} a hash off options to set on the server objects, see **Server** constructor**
 | 
			
		||||
 *  - **replSet** {Object, default: null} a hash off options to set on the replSet object, see **ReplSet** constructor**
 | 
			
		||||
 *  - **mongos** {Object, default: null} a hash off options to set on the mongos object, see **Mongos** constructor**
 | 
			
		||||
 *
 | 
			
		||||
 * @param {String} url connection url for MongoDB.
 | 
			
		||||
 * @param {Object} [options] optional options for insert command
 | 
			
		||||
 * @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the initialized db object or null if an error occured.
 | 
			
		||||
 * @return {null}
 | 
			
		||||
 * @api public
 | 
			
		||||
 */
 | 
			
		||||
MongoClient.connect = function(url, options, callback) {
 | 
			
		||||
  var args = Array.prototype.slice.call(arguments, 1);
 | 
			
		||||
  callback = typeof args[args.length - 1] == 'function' ? args.pop() : null;
 | 
			
		||||
  options = args.length ? args.shift() : null;
 | 
			
		||||
  options = options || {};
 | 
			
		||||
 | 
			
		||||
  // Set default empty server options  
 | 
			
		||||
  var serverOptions = options.server || {};
 | 
			
		||||
  var mongosOptions = options.mongos || {};
 | 
			
		||||
  var replSetServersOptions = options.replSet || options.replSetServers || {};
 | 
			
		||||
  var dbOptions = options.db || {};
 | 
			
		||||
 | 
			
		||||
  // If callback is null throw an exception
 | 
			
		||||
  if(callback == null) 
 | 
			
		||||
    throw new Error("no callback function provided");
 | 
			
		||||
 | 
			
		||||
  // Parse the string
 | 
			
		||||
  var object = parse(url, options);
 | 
			
		||||
 | 
			
		||||
  // Merge in any options for db in options object
 | 
			
		||||
  if(dbOptions) {
 | 
			
		||||
    for(var name in dbOptions) object.db_options[name] = dbOptions[name];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Added the url to the options
 | 
			
		||||
  object.db_options.url = url;
 | 
			
		||||
 | 
			
		||||
  // Merge in any options for server in options object
 | 
			
		||||
  if(serverOptions) {
 | 
			
		||||
    for(var name in serverOptions) object.server_options[name] = serverOptions[name];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Merge in any replicaset server options
 | 
			
		||||
  if(replSetServersOptions) {
 | 
			
		||||
    for(var name in replSetServersOptions) object.rs_options[name] = replSetServersOptions[name];    
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Merge in any replicaset server options
 | 
			
		||||
  if(mongosOptions) {
 | 
			
		||||
    for(var name in mongosOptions) object.mongos_options[name] = mongosOptions[name];    
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // We need to ensure that the list of servers are only either direct members or mongos
 | 
			
		||||
  // they cannot be a mix of monogs and mongod's
 | 
			
		||||
  var totalNumberOfServers = object.servers.length;
 | 
			
		||||
  var totalNumberOfMongosServers = 0;
 | 
			
		||||
  var totalNumberOfMongodServers = 0;
 | 
			
		||||
  var serverConfig = null;
 | 
			
		||||
  var errorServers = {};
 | 
			
		||||
 | 
			
		||||
  // Failure modes
 | 
			
		||||
  if(object.servers.length == 0) throw new Error("connection string must contain at least one seed host");
 | 
			
		||||
 | 
			
		||||
  // If we have no db setting for the native parser try to set the c++ one first
 | 
			
		||||
  object.db_options.native_parser = _setNativeParser(object.db_options);
 | 
			
		||||
  // If no auto_reconnect is set, set it to true as default for single servers
 | 
			
		||||
  if(typeof object.server_options.auto_reconnect != 'boolean') {
 | 
			
		||||
    object.server_options.auto_reconnect = true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Establish the correct socketTimeout
 | 
			
		||||
  var connectTimeoutMS = 30000;
 | 
			
		||||
  var socketTimeoutMS = 0;
 | 
			
		||||
 | 
			
		||||
  // We have a server connection timeout setting
 | 
			
		||||
  if(object.server_options && object.server_options.socketOptions && object.server_options.socketOptions.connectTimeoutMS) {
 | 
			
		||||
    connectTimeoutMS = object.server_options.socketOptions.connectTimeoutMS;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // We have a rs options set for connection timeout, override any server ones
 | 
			
		||||
  if(object.rs_options && object.rs_options.socketOptions && object.rs_options.socketOptions.connectTimeoutMS) {
 | 
			
		||||
    connectTimeoutMS = object.rs_options.socketOptions.connectTimeoutMS;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // If we have no socket settings set the default values
 | 
			
		||||
  if(object.rs_options.socketOptions.connectTimeoutMS == null) {
 | 
			
		||||
    object.rs_options.socketOptions.connectTimeoutMS = connectTimeoutMS;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(object.rs_options.socketOptions.socketTimeoutMS == null) {
 | 
			
		||||
    object.rs_options.socketOptions.socketTimeoutMS = socketTimeoutMS;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(object.server_options.socketOptions.connectTimeoutMS == null) {
 | 
			
		||||
    object.server_options.socketOptions.connectTimeoutMS = connectTimeoutMS;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(object.server_options.socketOptions.socketTimeoutMS == null) {
 | 
			
		||||
    object.server_options.socketOptions.socketTimeoutMS = socketTimeoutMS;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // If we have more than a server, it could be replicaset or mongos list
 | 
			
		||||
  // need to verify that it's one or the other and fail if it's a mix
 | 
			
		||||
  // Connect to all servers and run ismaster
 | 
			
		||||
  for(var i = 0; i < object.servers.length; i++) {
 | 
			
		||||
    // Set up socket options
 | 
			
		||||
    var _server_options = {
 | 
			
		||||
        poolSize:1
 | 
			
		||||
      , socketOptions: {
 | 
			
		||||
          connectTimeoutMS: connectTimeoutMS 
 | 
			
		||||
        , socketTimeoutMS: socketTimeoutMS
 | 
			
		||||
      }
 | 
			
		||||
      , auto_reconnect:false};
 | 
			
		||||
 | 
			
		||||
    // Ensure we have ssl setup for the servers
 | 
			
		||||
    if(object.rs_options.ssl) {
 | 
			
		||||
      _server_options.ssl = object.rs_options.ssl;
 | 
			
		||||
      _server_options.sslValidate = object.rs_options.sslValidate;
 | 
			
		||||
      _server_options.sslCA = object.rs_options.sslCA;
 | 
			
		||||
      _server_options.sslCert = object.rs_options.sslCert;
 | 
			
		||||
      _server_options.sslKey = object.rs_options.sslKey;
 | 
			
		||||
      _server_options.sslPass = object.rs_options.sslPass;
 | 
			
		||||
    } else if(object.server_options.ssl) {
 | 
			
		||||
      _server_options.ssl = object.server_options.ssl;
 | 
			
		||||
      _server_options.sslValidate = object.server_options.sslValidate;
 | 
			
		||||
      _server_options.sslCA = object.server_options.sslCA;
 | 
			
		||||
      _server_options.sslCert = object.server_options.sslCert;
 | 
			
		||||
      _server_options.sslKey = object.server_options.sslKey;
 | 
			
		||||
      _server_options.sslPass = object.server_options.sslPass;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Set up the Server object
 | 
			
		||||
    var _server = object.servers[i].domain_socket 
 | 
			
		||||
        ? new Server(object.servers[i].domain_socket, _server_options)
 | 
			
		||||
        : new Server(object.servers[i].host, object.servers[i].port, _server_options);
 | 
			
		||||
 | 
			
		||||
    var connectFunction = function(__server) { 
 | 
			
		||||
      // Attempt connect
 | 
			
		||||
      new Db(object.dbName, __server, {w:1, native_parser:false}).open(function(err, db) {
 | 
			
		||||
        // Update number of servers
 | 
			
		||||
        totalNumberOfServers = totalNumberOfServers - 1;          
 | 
			
		||||
        // If no error do the correct checks
 | 
			
		||||
        if(!err) {
 | 
			
		||||
          // Close the connection
 | 
			
		||||
          db.close(true);
 | 
			
		||||
          var isMasterDoc = db.serverConfig.isMasterDoc;
 | 
			
		||||
          // Check what type of server we have
 | 
			
		||||
          if(isMasterDoc.setName) totalNumberOfMongodServers++;
 | 
			
		||||
          if(isMasterDoc.msg && isMasterDoc.msg == "isdbgrid") totalNumberOfMongosServers++;
 | 
			
		||||
        } else {
 | 
			
		||||
          errorServers[__server.host + ":" + __server.port] = __server;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(totalNumberOfServers == 0) {
 | 
			
		||||
          // If we have a mix of mongod and mongos, throw an error
 | 
			
		||||
          if(totalNumberOfMongosServers > 0 && totalNumberOfMongodServers > 0) {
 | 
			
		||||
            return process.nextTick(function() {
 | 
			
		||||
              try {
 | 
			
		||||
                callback(new Error("cannot combine a list of replicaset seeds and mongos seeds"));
 | 
			
		||||
              } catch (err) {
 | 
			
		||||
                if(db) db.close();
 | 
			
		||||
                throw err
 | 
			
		||||
              }              
 | 
			
		||||
            })
 | 
			
		||||
          }
 | 
			
		||||
          
 | 
			
		||||
          if(totalNumberOfMongodServers == 0 && object.servers.length == 1) {
 | 
			
		||||
            var obj = object.servers[0];
 | 
			
		||||
            serverConfig = obj.domain_socket ? 
 | 
			
		||||
                new Server(obj.domain_socket, object.server_options)
 | 
			
		||||
              : new Server(obj.host, obj.port, object.server_options);            
 | 
			
		||||
          } else if(totalNumberOfMongodServers > 0 || totalNumberOfMongosServers > 0) {
 | 
			
		||||
            var finalServers = object.servers
 | 
			
		||||
              .filter(function(serverObj) {
 | 
			
		||||
                return errorServers[serverObj.host + ":" + serverObj.port] == null;
 | 
			
		||||
              })
 | 
			
		||||
              .map(function(serverObj) {
 | 
			
		||||
                  return new Server(serverObj.host, serverObj.port, object.server_options);
 | 
			
		||||
              });
 | 
			
		||||
            // Clean out any error servers
 | 
			
		||||
            errorServers = {};
 | 
			
		||||
            // Set up the final configuration
 | 
			
		||||
            if(totalNumberOfMongodServers > 0) {
 | 
			
		||||
              serverConfig = new ReplSet(finalServers, object.rs_options);                
 | 
			
		||||
            } else {
 | 
			
		||||
              serverConfig = new Mongos(finalServers, object.mongos_options);                         
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          if(serverConfig == null) {
 | 
			
		||||
            return process.nextTick(function() {
 | 
			
		||||
              try {
 | 
			
		||||
                callback(new Error("Could not locate any valid servers in initial seed list"));
 | 
			
		||||
              } catch (err) {
 | 
			
		||||
                if(db) db.close();
 | 
			
		||||
                throw err
 | 
			
		||||
              }
 | 
			
		||||
            });
 | 
			
		||||
          }
 | 
			
		||||
          // Ensure no firing off open event before we are ready
 | 
			
		||||
          serverConfig.emitOpen = false;
 | 
			
		||||
          // Set up all options etc and connect to the database
 | 
			
		||||
          _finishConnecting(serverConfig, object, options, callback)
 | 
			
		||||
        }
 | 
			
		||||
      });        
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Wrap the context of the call
 | 
			
		||||
    connectFunction(_server);    
 | 
			
		||||
  }    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _setNativeParser = function(db_options) {
 | 
			
		||||
  if(typeof db_options.native_parser == 'boolean') return db_options.native_parser;
 | 
			
		||||
 | 
			
		||||
  try {
 | 
			
		||||
    require('bson').BSONNative.BSON;
 | 
			
		||||
    return true;
 | 
			
		||||
  } catch(err) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _finishConnecting = function(serverConfig, object, options, callback) {
 | 
			
		||||
  // Safe settings
 | 
			
		||||
  var safe = {};
 | 
			
		||||
  // Build the safe parameter if needed
 | 
			
		||||
  if(object.db_options.journal) safe.j = object.db_options.journal;
 | 
			
		||||
  if(object.db_options.w) safe.w = object.db_options.w;
 | 
			
		||||
  if(object.db_options.fsync) safe.fsync = object.db_options.fsync;
 | 
			
		||||
  if(object.db_options.wtimeoutMS) safe.wtimeout = object.db_options.wtimeoutMS;
 | 
			
		||||
 | 
			
		||||
  // If we have a read Preference set
 | 
			
		||||
  if(object.db_options.read_preference) {
 | 
			
		||||
    var readPreference = new ReadPreference(object.db_options.read_preference);
 | 
			
		||||
    // If we have the tags set up
 | 
			
		||||
    if(object.db_options.read_preference_tags)
 | 
			
		||||
      readPreference = new ReadPreference(object.db_options.read_preference, object.db_options.read_preference_tags);
 | 
			
		||||
    // Add the read preference
 | 
			
		||||
    object.db_options.readPreference = readPreference;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // No safe mode if no keys
 | 
			
		||||
  if(Object.keys(safe).length == 0) safe = false;
 | 
			
		||||
 | 
			
		||||
  // Add the safe object
 | 
			
		||||
  object.db_options.safe = safe;
 | 
			
		||||
 | 
			
		||||
  // Get the socketTimeoutMS
 | 
			
		||||
  var socketTimeoutMS = object.server_options.socketOptions.socketTimeoutMS || 0;
 | 
			
		||||
  var connectTimeoutMS = object.server_options.socketOptions.connectTimeoutMS || 30000;
 | 
			
		||||
 | 
			
		||||
  // If we have a replset, override with replicaset socket timeout option if available
 | 
			
		||||
  if(serverConfig instanceof ReplSet) {
 | 
			
		||||
    socketTimeoutMS = object.rs_options.socketOptions.socketTimeoutMS || socketTimeoutMS;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  // Set socketTimeout to same as connectionTimeout to ensure we don't block on connect and auth
 | 
			
		||||
  // This is a workaround for pre 2.6 servers where auth can hang when indexes are build on secondaries
 | 
			
		||||
  serverConfig.setSocketOptions({socketTimeoutMS: connectTimeoutMS, connectTimeoutMS: connectTimeoutMS});
 | 
			
		||||
 | 
			
		||||
  // Set up the db options
 | 
			
		||||
  var db = new Db(object.dbName, serverConfig, object.db_options);
 | 
			
		||||
  // Open the db
 | 
			
		||||
  db.open(function(err, db){
 | 
			
		||||
    if(err) {
 | 
			
		||||
      return process.nextTick(function() {
 | 
			
		||||
        try {
 | 
			
		||||
          callback(err, null);
 | 
			
		||||
        } catch (err) {
 | 
			
		||||
          if(db) db.close();
 | 
			
		||||
          throw err
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // Set socketTimeout to same as connectionTimeout to ensure we don't block on connect and auth
 | 
			
		||||
    // This is a workaround for pre 2.6 servers where auth can hang when indexes are build on secondaries
 | 
			
		||||
    serverConfig.setSocketOptions({socketTimeoutMS: connectTimeoutMS, connectTimeoutMS: connectTimeoutMS});
 | 
			
		||||
 | 
			
		||||
    // Set the provided write concern or fall back to w:1 as default
 | 
			
		||||
    if(db.options !== null && !db.options.safe && !db.options.journal 
 | 
			
		||||
      && !db.options.w && !db.options.fsync && typeof db.options.w != 'number'
 | 
			
		||||
      && (db.options.safe == false && object.db_options.url.indexOf("safe=") == -1)) {
 | 
			
		||||
        db.options.w = 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(err == null && object.auth){
 | 
			
		||||
      // What db to authenticate against
 | 
			
		||||
      var authentication_db = db;
 | 
			
		||||
      if(object.db_options && object.db_options.authSource) {
 | 
			
		||||
        authentication_db = db.db(object.db_options.authSource);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Build options object
 | 
			
		||||
      var options = {};
 | 
			
		||||
      if(object.db_options.authMechanism) options.authMechanism = object.db_options.authMechanism;
 | 
			
		||||
      if(object.db_options.gssapiServiceName) options.gssapiServiceName = object.db_options.gssapiServiceName;
 | 
			
		||||
 | 
			
		||||
      // Authenticate
 | 
			
		||||
      authentication_db.authenticate(object.auth.user, object.auth.password, options, function(err, success){
 | 
			
		||||
        // Reset the socket timeout
 | 
			
		||||
        serverConfig.setSocketOptions({socketTimeoutMS: socketTimeoutMS, connectTimeoutMS: connectTimeoutMS});
 | 
			
		||||
 | 
			
		||||
        // Handle the results
 | 
			
		||||
        if(success){
 | 
			
		||||
          process.nextTick(function() {
 | 
			
		||||
            try {
 | 
			
		||||
              callback(null, db);            
 | 
			
		||||
            } catch (err) {
 | 
			
		||||
              if(db) db.close();
 | 
			
		||||
              throw err
 | 
			
		||||
            }
 | 
			
		||||
          });
 | 
			
		||||
        } else {
 | 
			
		||||
          if(db) db.close();
 | 
			
		||||
          process.nextTick(function() {
 | 
			
		||||
            try {
 | 
			
		||||
              callback(err ? err : new Error('Could not authenticate user ' + object.auth[0]), null);
 | 
			
		||||
            } catch (err) {
 | 
			
		||||
              if(db) db.close();
 | 
			
		||||
              throw err
 | 
			
		||||
            }
 | 
			
		||||
          });
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
    } else {      
 | 
			
		||||
      // Reset the socket timeout
 | 
			
		||||
      serverConfig.setSocketOptions({socketTimeoutMS: socketTimeoutMS, connectTimeoutMS: connectTimeoutMS});
 | 
			
		||||
 | 
			
		||||
      // Return connection      
 | 
			
		||||
      process.nextTick(function() {
 | 
			
		||||
        try {
 | 
			
		||||
          callback(err, db);            
 | 
			
		||||
        } catch (err) {
 | 
			
		||||
          if(db) db.close();
 | 
			
		||||
          throw err
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.MongoClient = MongoClient;
 | 
			
		||||
							
								
								
									
										83
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										83
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,83 @@
 | 
			
		||||
var Long = require('bson').Long
 | 
			
		||||
  , timers = require('timers');
 | 
			
		||||
 | 
			
		||||
// Set processor, setImmediate if 0.10 otherwise nextTick
 | 
			
		||||
var processor = require('../utils').processor();
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  Reply message from mongo db
 | 
			
		||||
**/
 | 
			
		||||
var MongoReply = exports.MongoReply = function() {
 | 
			
		||||
  this.documents = [];
 | 
			
		||||
  this.index = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
MongoReply.prototype.parseHeader = function(binary_reply, bson) {
 | 
			
		||||
  // Unpack the standard header first
 | 
			
		||||
  this.messageLength = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
 | 
			
		||||
  this.index = this.index + 4;
 | 
			
		||||
  // Fetch the request id for this reply
 | 
			
		||||
  this.requestId = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
 | 
			
		||||
  this.index = this.index + 4;
 | 
			
		||||
  // Fetch the id of the request that triggered the response
 | 
			
		||||
  this.responseTo = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
 | 
			
		||||
  // Skip op-code field
 | 
			
		||||
  this.index = this.index + 4 + 4;
 | 
			
		||||
  // Unpack the reply message
 | 
			
		||||
  this.responseFlag = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
 | 
			
		||||
  this.index = this.index + 4;
 | 
			
		||||
  // Unpack the cursor id (a 64 bit long integer)
 | 
			
		||||
  var low_bits = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
 | 
			
		||||
  this.index = this.index + 4;
 | 
			
		||||
  var high_bits = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
 | 
			
		||||
  this.index = this.index + 4;
 | 
			
		||||
  this.cursorId = new Long(low_bits, high_bits);
 | 
			
		||||
  // Unpack the starting from
 | 
			
		||||
  this.startingFrom = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
 | 
			
		||||
  this.index = this.index + 4;
 | 
			
		||||
  // Unpack the number of objects returned
 | 
			
		||||
  this.numberReturned = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
 | 
			
		||||
  this.index = this.index + 4;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MongoReply.prototype.parseBody = function(binary_reply, bson, raw, callback) {
 | 
			
		||||
  raw = raw == null ? false : raw;
 | 
			
		||||
 | 
			
		||||
  try {
 | 
			
		||||
    // Let's unpack all the bson documents, deserialize them and store them
 | 
			
		||||
    for(var object_index = 0; object_index < this.numberReturned; object_index++) {
 | 
			
		||||
      var _options = {promoteLongs: bson.promoteLongs};
 | 
			
		||||
      
 | 
			
		||||
      // Read the size of the bson object
 | 
			
		||||
      var bsonObjectSize = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
 | 
			
		||||
      
 | 
			
		||||
      // If we are storing the raw responses to pipe straight through
 | 
			
		||||
      if(raw) {
 | 
			
		||||
        // Deserialize the object and add to the documents array
 | 
			
		||||
        this.documents.push(binary_reply.slice(this.index, this.index + bsonObjectSize));
 | 
			
		||||
      } else {
 | 
			
		||||
        // Deserialize the object and add to the documents array
 | 
			
		||||
        this.documents.push(bson.deserialize(binary_reply.slice(this.index, this.index + bsonObjectSize), _options));
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      // Adjust binary index to point to next block of binary bson data
 | 
			
		||||
      this.index = this.index + bsonObjectSize;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // No error return
 | 
			
		||||
    callback(null);
 | 
			
		||||
  } catch(err) {
 | 
			
		||||
    return callback(err);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MongoReply.prototype.is_error = function(){
 | 
			
		||||
  if(this.documents.length == 1) {
 | 
			
		||||
    return this.documents[0].ok == 1 ? false : true;
 | 
			
		||||
  }
 | 
			
		||||
  return false;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
MongoReply.prototype.error_message = function() {
 | 
			
		||||
  return this.documents.length == 1 && this.documents[0].ok == 1 ? '' : this.documents[0].errmsg;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										86
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/scope.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										86
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/scope.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,86 @@
 | 
			
		||||
var Cursor = require('./cursor').Cursor
 | 
			
		||||
  , Readable = require('stream').Readable
 | 
			
		||||
  , utils = require('./utils')
 | 
			
		||||
  , inherits = require('util').inherits;
 | 
			
		||||
 | 
			
		||||
var Scope = function(collection, _selector, _fields, _scope_options) {
 | 
			
		||||
  var self = this;
 | 
			
		||||
 | 
			
		||||
  // Ensure we have at least an empty cursor options object
 | 
			
		||||
  _scope_options = _scope_options || {};
 | 
			
		||||
  var _write_concern = _scope_options.write_concern || null;
 | 
			
		||||
 | 
			
		||||
  // Ensure default read preference
 | 
			
		||||
  // if(!_scope_options.readPreference) _scope_options.readPreference = 'primary';
 | 
			
		||||
 | 
			
		||||
  // Set up the cursor
 | 
			
		||||
  var _cursor = new Cursor(
 | 
			
		||||
        collection.db, collection, _selector
 | 
			
		||||
      , _fields, _scope_options
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
  // Write branch options
 | 
			
		||||
  var writeOptions = {
 | 
			
		||||
    insert: function(documents, callback) {
 | 
			
		||||
      // Merge together options
 | 
			
		||||
      var options = _write_concern || {};
 | 
			
		||||
      // Execute insert
 | 
			
		||||
      collection.insert(documents, options, callback);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    save: function(document, callback) {
 | 
			
		||||
      // Merge together options
 | 
			
		||||
      var save_options = _write_concern || {};
 | 
			
		||||
      // Execute save
 | 
			
		||||
      collection.save(document, save_options, function(err, result) {
 | 
			
		||||
        if(typeof result == 'number' && result == 1) {
 | 
			
		||||
          return callback(null, document);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return callback(null, document);
 | 
			
		||||
      });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    find: function(selector) {
 | 
			
		||||
      _selector = selector;
 | 
			
		||||
      return writeOptions;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    //
 | 
			
		||||
    // Update is implicit multiple document update
 | 
			
		||||
    update: function(operations, callback) {
 | 
			
		||||
      // Merge together options
 | 
			
		||||
      var update_options = _write_concern || {};
 | 
			
		||||
 | 
			
		||||
      // Set up options, multi is default operation
 | 
			
		||||
      update_options.multi = _scope_options.multi ? _scope_options.multi : true;
 | 
			
		||||
      if(_scope_options.upsert) update_options.upsert = _scope_options.upsert;
 | 
			
		||||
 | 
			
		||||
      // Execute options
 | 
			
		||||
      collection.update(_selector, operations, update_options, function(err, result, obj) {
 | 
			
		||||
        callback(err, obj);
 | 
			
		||||
      });
 | 
			
		||||
    },
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Set write concern
 | 
			
		||||
  this.withWriteConcern = function(write_concern) {
 | 
			
		||||
    // Save the current write concern to the Scope
 | 
			
		||||
    _scope_options.write_concern = write_concern;
 | 
			
		||||
    _write_concern = write_concern;
 | 
			
		||||
    // Only allow legal options
 | 
			
		||||
    return writeOptions;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Start find
 | 
			
		||||
  this.find = function(selector, options) {
 | 
			
		||||
    // Save the current selector
 | 
			
		||||
    _selector = selector;
 | 
			
		||||
    // Set the cursor
 | 
			
		||||
    _cursor.selector = selector;
 | 
			
		||||
    // Return only legal read options
 | 
			
		||||
    return Cursor.cloneWithOptions(_cursor, _scope_options);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.Scope = Scope;
 | 
			
		||||
							
								
								
									
										286
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/utils.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										286
									
								
								server/node_modules/monk/node_modules/mongodb/lib/mongodb/utils.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,286 @@
 | 
			
		||||
var timers = require('timers');
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Sort functions, Normalize and prepare sort parameters
 | 
			
		||||
 */
 | 
			
		||||
var formatSortValue = exports.formatSortValue = function(sortDirection) {
 | 
			
		||||
  var value = ("" + sortDirection).toLowerCase();
 | 
			
		||||
 | 
			
		||||
  switch (value) {
 | 
			
		||||
    case 'ascending':
 | 
			
		||||
    case 'asc':
 | 
			
		||||
    case '1':
 | 
			
		||||
      return 1;
 | 
			
		||||
    case 'descending':
 | 
			
		||||
    case 'desc':
 | 
			
		||||
    case '-1':
 | 
			
		||||
      return -1;
 | 
			
		||||
    default:
 | 
			
		||||
      throw new Error("Illegal sort clause, must be of the form "
 | 
			
		||||
                    + "[['field1', '(ascending|descending)'], "
 | 
			
		||||
                    + "['field2', '(ascending|descending)']]");
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
var formattedOrderClause = exports.formattedOrderClause = function(sortValue) {
 | 
			
		||||
  var orderBy = {};
 | 
			
		||||
  if(sortValue == null) return null;
 | 
			
		||||
  if (Array.isArray(sortValue)) {
 | 
			
		||||
    if(sortValue.length === 0) {
 | 
			
		||||
      return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for(var i = 0; i < sortValue.length; i++) {
 | 
			
		||||
      if(sortValue[i].constructor == String) {
 | 
			
		||||
        orderBy[sortValue[i]] = 1;
 | 
			
		||||
      } else {
 | 
			
		||||
        orderBy[sortValue[i][0]] = formatSortValue(sortValue[i][1]);
 | 
			
		||||
      }      
 | 
			
		||||
    }
 | 
			
		||||
  } else if(sortValue != null && typeof sortValue == 'object') {
 | 
			
		||||
    orderBy = sortValue;
 | 
			
		||||
  } else if (typeof sortValue == 'string') {
 | 
			
		||||
    orderBy[sortValue] = 1;
 | 
			
		||||
  } else {
 | 
			
		||||
    throw new Error("Illegal sort clause, must be of the form " +
 | 
			
		||||
      "[['field1', '(ascending|descending)'], ['field2', '(ascending|descending)']]");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return orderBy;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
exports.encodeInt = function(value) {
 | 
			
		||||
  var buffer = new Buffer(4);
 | 
			
		||||
  buffer[3] = (value >> 24) & 0xff;      
 | 
			
		||||
  buffer[2] = (value >> 16) & 0xff;
 | 
			
		||||
  buffer[1] = (value >> 8) & 0xff;
 | 
			
		||||
  buffer[0] = value & 0xff;
 | 
			
		||||
  return buffer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.encodeIntInPlace = function(value, buffer, index) {
 | 
			
		||||
  buffer[index + 3] = (value >> 24) & 0xff;			
 | 
			
		||||
	buffer[index + 2] = (value >> 16) & 0xff;
 | 
			
		||||
	buffer[index + 1] = (value >> 8) & 0xff;
 | 
			
		||||
	buffer[index] = value & 0xff;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.encodeCString = function(string) {
 | 
			
		||||
  var buf = new Buffer(string, 'utf8');
 | 
			
		||||
  return [buf, new Buffer([0])];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.decodeUInt32 = function(array, index) {
 | 
			
		||||
  return array[index] | array[index + 1] << 8 | array[index + 2] << 16 | array[index + 3] << 24;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Decode the int
 | 
			
		||||
exports.decodeUInt8 = function(array, index) {
 | 
			
		||||
  return array[index];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Context insensitive type checks
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
var toString = Object.prototype.toString;
 | 
			
		||||
 | 
			
		||||
var isObject = exports.isObject = function (arg) {
 | 
			
		||||
  return '[object Object]' == toString.call(arg)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.isArray = function (arg) {
 | 
			
		||||
  return Array.isArray(arg) ||
 | 
			
		||||
    'object' == typeof arg && '[object Array]' == toString.call(arg)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.isDate = function (arg) {
 | 
			
		||||
  return 'object' == typeof arg && '[object Date]' == toString.call(arg)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.isRegExp = function (arg) {
 | 
			
		||||
  return 'object' == typeof arg && '[object RegExp]' == toString.call(arg)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Wrap a Mongo error document in an Error instance
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
var toError = function(error) {
 | 
			
		||||
  if (error instanceof Error) return error;
 | 
			
		||||
 | 
			
		||||
  var msg = error.err || error.errmsg || error.errMessage || error.$err || error;
 | 
			
		||||
  var e = new Error(msg);
 | 
			
		||||
  e.name = 'MongoError';
 | 
			
		||||
 | 
			
		||||
  // Get all object keys
 | 
			
		||||
  var keys = typeof error == 'object'
 | 
			
		||||
    ? Object.keys(error)
 | 
			
		||||
    : [];
 | 
			
		||||
 | 
			
		||||
  for(var i = 0; i < keys.length; i++) {
 | 
			
		||||
    e[keys[i]] = error[keys[i]];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return e;
 | 
			
		||||
}
 | 
			
		||||
exports.toError = toError;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Convert a single level object to an array
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
exports.objectToArray = function(object) {
 | 
			
		||||
  var list = [];
 | 
			
		||||
 | 
			
		||||
  for(var name in object) {
 | 
			
		||||
    list.push(object[name])
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return list;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handle single command document return
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
exports.handleSingleCommandResultReturn = function(override_value_true, override_value_false, callback) {
 | 
			
		||||
  return function(err, result, connection) {
 | 
			
		||||
    if(callback == null) return;
 | 
			
		||||
    if(err && typeof callback == 'function') return callback(err, null);
 | 
			
		||||
    if(!result || !result.documents || result.documents.length == 0)
 | 
			
		||||
      if(typeof callback == 'function') return callback(toError("command failed to return results"), null)
 | 
			
		||||
    if(result && result.documents[0].ok == 1) {
 | 
			
		||||
      if(override_value_true) return callback(null, override_value_true)
 | 
			
		||||
      if(typeof callback == 'function') return callback(null, result.documents[0]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Return the error from the document
 | 
			
		||||
    if(typeof callback == 'function') return callback(toError(result.documents[0]), override_value_false);    
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Return correct processor
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
exports.processor = function() {
 | 
			
		||||
  // Set processor, setImmediate if 0.10 otherwise nextTick
 | 
			
		||||
  process.maxTickDepth = Infinity;
 | 
			
		||||
  // Only use nextTick
 | 
			
		||||
  return process.nextTick;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Allow setting the socketTimeoutMS on all connections
 | 
			
		||||
 * to work around issues such as secondaries blocking due to compaction
 | 
			
		||||
 *
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
exports.setSocketTimeoutProperty = function(self, options) {
 | 
			
		||||
  Object.defineProperty(self, "socketTimeoutMS", {
 | 
			
		||||
      enumerable: true
 | 
			
		||||
    , get: function () { return options.socketTimeoutMS; }
 | 
			
		||||
    , set: function (value) { 
 | 
			
		||||
      // Set the socket timeoutMS value
 | 
			
		||||
      options.socketTimeoutMS = value;
 | 
			
		||||
 | 
			
		||||
      // Get all the connections
 | 
			
		||||
      var connections = self.allRawConnections();
 | 
			
		||||
      for(var i = 0; i < connections.length; i++) {
 | 
			
		||||
        connections[i].socketTimeoutMS = value;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  });  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Determine if the server supports write commands
 | 
			
		||||
 *
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
exports.hasWriteCommands = function(connection) {
 | 
			
		||||
  return connection != null && connection.serverCapabilities != null && connection.serverCapabilities.hasWriteCommands;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Fetch server capabilities
 | 
			
		||||
 *
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
exports.serverCapabilities = function(connection) {
 | 
			
		||||
  return connection != null && connection.serverCapabilities != null && connection.serverCapabilities.hasWriteCommands;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create index name based on field spec
 | 
			
		||||
 *
 | 
			
		||||
 * @ignore
 | 
			
		||||
 * @api private
 | 
			
		||||
 */
 | 
			
		||||
exports.parseIndexOptions = function(fieldOrSpec) {
 | 
			
		||||
  var fieldHash = {};
 | 
			
		||||
  var indexes = [];
 | 
			
		||||
  var keys;
 | 
			
		||||
 | 
			
		||||
  // Get all the fields accordingly
 | 
			
		||||
  if('string' == typeof fieldOrSpec) {
 | 
			
		||||
    // 'type'
 | 
			
		||||
    indexes.push(fieldOrSpec + '_' + 1);
 | 
			
		||||
    fieldHash[fieldOrSpec] = 1;
 | 
			
		||||
  } else if(Array.isArray(fieldOrSpec)) {
 | 
			
		||||
    fieldOrSpec.forEach(function(f) {
 | 
			
		||||
      if('string' == typeof f) {
 | 
			
		||||
        // [{location:'2d'}, 'type']
 | 
			
		||||
        indexes.push(f + '_' + 1);
 | 
			
		||||
        fieldHash[f] = 1;
 | 
			
		||||
      } else if(Array.isArray(f)) {
 | 
			
		||||
        // [['location', '2d'],['type', 1]]
 | 
			
		||||
        indexes.push(f[0] + '_' + (f[1] || 1));
 | 
			
		||||
        fieldHash[f[0]] = f[1] || 1;
 | 
			
		||||
      } else if(isObject(f)) {
 | 
			
		||||
        // [{location:'2d'}, {type:1}]
 | 
			
		||||
        keys = Object.keys(f);
 | 
			
		||||
        keys.forEach(function(k) {
 | 
			
		||||
          indexes.push(k + '_' + f[k]);
 | 
			
		||||
          fieldHash[k] = f[k];
 | 
			
		||||
        });
 | 
			
		||||
      } else {
 | 
			
		||||
        // undefined (ignore)
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  } else if(isObject(fieldOrSpec)) {
 | 
			
		||||
    // {location:'2d', type:1}
 | 
			
		||||
    keys = Object.keys(fieldOrSpec);
 | 
			
		||||
    keys.forEach(function(key) {
 | 
			
		||||
      indexes.push(key + '_' + fieldOrSpec[key]);
 | 
			
		||||
      fieldHash[key] = fieldOrSpec[key];
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
    name: indexes.join("_"), keys: keys, fieldHash: fieldHash
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.decorateCommand = function(command, options, exclude) {
 | 
			
		||||
  for(var name in options) {
 | 
			
		||||
    if(exclude[name] == null) command[name] = options[name];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return command;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exports.shallowObjectCopy = function(object) {
 | 
			
		||||
  var c = {};
 | 
			
		||||
  for(var n in object) c[n] = object[n];
 | 
			
		||||
  return c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								server/node_modules/monk/node_modules/mongodb/node_modules/bson/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										4
									
								
								server/node_modules/monk/node_modules/mongodb/node_modules/bson/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
language: node_js
 | 
			
		||||
node_js:
 | 
			
		||||
  - 0.10 # development version of 0.8, may be unstable
 | 
			
		||||
  - 0.12
 | 
			
		||||
							
								
								
									
										30
									
								
								server/node_modules/monk/node_modules/mongodb/node_modules/bson/HISTORY
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										30
									
								
								server/node_modules/monk/node_modules/mongodb/node_modules/bson/HISTORY
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
0.2.21 2015-03-21
 | 
			
		||||
-----------------
 | 
			
		||||
- Updated Nan to 1.7.0 to support io.js and node 0.12.0
 | 
			
		||||
 | 
			
		||||
0.2.19 2015-02-16
 | 
			
		||||
-----------------
 | 
			
		||||
- Updated Nan to 1.6.2 to support io.js and node 0.12.0
 | 
			
		||||
 | 
			
		||||
0.2.18 2015-01-20
 | 
			
		||||
-----------------
 | 
			
		||||
- Updated Nan to 1.5.1 to support io.js
 | 
			
		||||
 | 
			
		||||
0.2.16 2014-12-17
 | 
			
		||||
-----------------
 | 
			
		||||
- Made pid cycle on 0xffff to avoid weird overflows on creation of ObjectID's
 | 
			
		||||
 | 
			
		||||
0.2.12 2014-08-24
 | 
			
		||||
-----------------
 | 
			
		||||
- Fixes for fortify review of c++ extension
 | 
			
		||||
- toBSON correctly allows returns of non objects
 | 
			
		||||
 | 
			
		||||
0.2.3 2013-10-01
 | 
			
		||||
----------------
 | 
			
		||||
- Drying of ObjectId code for generation of id (Issue #54, https://github.com/moredip)
 | 
			
		||||
- Fixed issue where corrupt CString's could cause endless loop
 | 
			
		||||
- Support for Node 0.11.X > (Issue #49, https://github.com/kkoopa)
 | 
			
		||||
 | 
			
		||||
0.1.4 2012-09-25
 | 
			
		||||
----------------
 | 
			
		||||
- Added precompiled c++ native extensions for win32 ia32 and x64
 | 
			
		||||
							
								
								
									
										201
									
								
								server/node_modules/monk/node_modules/mongodb/node_modules/bson/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										201
									
								
								server/node_modules/monk/node_modules/mongodb/node_modules/bson/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,201 @@
 | 
			
		||||
                                 Apache License
 | 
			
		||||
                           Version 2.0, January 2004
 | 
			
		||||
                        http://www.apache.org/licenses/
 | 
			
		||||
 | 
			
		||||
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
			
		||||
 | 
			
		||||
   1. Definitions.
 | 
			
		||||
 | 
			
		||||
      "License" shall mean the terms and conditions for use, reproduction,
 | 
			
		||||
      and distribution as defined by Sections 1 through 9 of this document.
 | 
			
		||||
 | 
			
		||||
      "Licensor" shall mean the copyright owner or entity authorized by
 | 
			
		||||
      the copyright owner that is granting the License.
 | 
			
		||||
 | 
			
		||||
      "Legal Entity" shall mean the union of the acting entity and all
 | 
			
		||||
      other entities that control, are controlled by, or are under common
 | 
			
		||||
      control with that entity. For the purposes of this definition,
 | 
			
		||||
      "control" means (i) the power, direct or indirect, to cause the
 | 
			
		||||
      direction or management of such entity, whether by contract or
 | 
			
		||||
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
			
		||||
      outstanding shares, or (iii) beneficial ownership of such entity.
 | 
			
		||||
 | 
			
		||||
      "You" (or "Your") shall mean an individual or Legal Entity
 | 
			
		||||
      exercising permissions granted by this License.
 | 
			
		||||
 | 
			
		||||
      "Source" form shall mean the preferred form for making modifications,
 | 
			
		||||
      including but not limited to software source code, documentation
 | 
			
		||||
      source, and configuration files.
 | 
			
		||||
 | 
			
		||||
      "Object" form shall mean any form resulting from mechanical
 | 
			
		||||
      transformation or translation of a Source form, including but
 | 
			
		||||
      not limited to compiled object code, generated documentation,
 | 
			
		||||
      and conversions to other media types.
 | 
			
		||||
 | 
			
		||||
      "Work" shall mean the work of authorship, whether in Source or
 | 
			
		||||
      Object form, made available under the License, as indicated by a
 | 
			
		||||
      copyright notice that is included in or attached to the work
 | 
			
		||||
      (an example is provided in the Appendix below).
 | 
			
		||||
 | 
			
		||||
      "Derivative Works" shall mean any work, whether in Source or Object
 | 
			
		||||
      form, that is based on (or derived from) the Work and for which the
 | 
			
		||||
      editorial revisions, annotations, elaborations, or other modifications
 | 
			
		||||
      represent, as a whole, an original work of authorship. For the purposes
 | 
			
		||||
      of this License, Derivative Works shall not include works that remain
 | 
			
		||||
      separable from, or merely link (or bind by name) to the interfaces of,
 | 
			
		||||
      the Work and Derivative Works thereof.
 | 
			
		||||
 | 
			
		||||
      "Contribution" shall mean any work of authorship, including
 | 
			
		||||
      the original version of the Work and any modifications or additions
 | 
			
		||||
      to that Work or Derivative Works thereof, that is intentionally
 | 
			
		||||
      submitted to Licensor for inclusion in the Work by the copyright owner
 | 
			
		||||
      or by an individual or Legal Entity authorized to submit on behalf of
 | 
			
		||||
      the copyright owner. For the purposes of this definition, "submitted"
 | 
			
		||||
      means any form of electronic, verbal, or written communication sent
 | 
			
		||||
      to the Licensor or its representatives, including but not limited to
 | 
			
		||||
      communication on electronic mailing lists, source code control systems,
 | 
			
		||||
      and issue tracking systems that are managed by, or on behalf of, the
 | 
			
		||||
      Licensor for the purpose of discussing and improving the Work, but
 | 
			
		||||
      excluding communication that is conspicuously marked or otherwise
 | 
			
		||||
      designated in writing by the copyright owner as "Not a Contribution."
 | 
			
		||||
 | 
			
		||||
      "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
			
		||||
      on behalf of whom a Contribution has been received by Licensor and
 | 
			
		||||
      subsequently incorporated within the Work.
 | 
			
		||||
 | 
			
		||||
   2. Grant of Copyright License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      copyright license to reproduce, prepare Derivative Works of,
 | 
			
		||||
      publicly display, publicly perform, sublicense, and distribute the
 | 
			
		||||
      Work and such Derivative Works in Source or Object form.
 | 
			
		||||
 | 
			
		||||
   3. Grant of Patent License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      (except as stated in this section) patent license to make, have made,
 | 
			
		||||
      use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
			
		||||
      where such license applies only to those patent claims licensable
 | 
			
		||||
      by such Contributor that are necessarily infringed by their
 | 
			
		||||
      Contribution(s) alone or by combination of their Contribution(s)
 | 
			
		||||
      with the Work to which such Contribution(s) was submitted. If You
 | 
			
		||||
      institute patent litigation against any entity (including a
 | 
			
		||||
      cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
			
		||||
      or a Contribution incorporated within the Work constitutes direct
 | 
			
		||||
      or contributory patent infringement, then any patent licenses
 | 
			
		||||
      granted to You under this License for that Work shall terminate
 | 
			
		||||
      as of the date such litigation is filed.
 | 
			
		||||
 | 
			
		||||
   4. Redistribution. You may reproduce and distribute copies of the
 | 
			
		||||
      Work or Derivative Works thereof in any medium, with or without
 | 
			
		||||
      modifications, and in Source or Object form, provided that You
 | 
			
		||||
      meet the following conditions:
 | 
			
		||||
 | 
			
		||||
      (a) You must give any other recipients of the Work or
 | 
			
		||||
          Derivative Works a copy of this License; and
 | 
			
		||||
 | 
			
		||||
      (b) You must cause any modified files to carry prominent notices
 | 
			
		||||
          stating that You changed the files; and
 | 
			
		||||
 | 
			
		||||
      (c) You must retain, in the Source form of any Derivative Works
 | 
			
		||||
          that You distribute, all copyright, patent, trademark, and
 | 
			
		||||
          attribution notices from the Source form of the Work,
 | 
			
		||||
          excluding those notices that do not pertain to any part of
 | 
			
		||||
          the Derivative Works; and
 | 
			
		||||
 | 
			
		||||
      (d) If the Work includes a "NOTICE" text file as part of its
 | 
			
		||||
          distribution, then any Derivative Works that You distribute must
 | 
			
		||||
          include a readable copy of the attribution notices contained
 | 
			
		||||
          within such NOTICE file, excluding those notices that do not
 | 
			
		||||
          pertain to any part of the Derivative Works, in at least one
 | 
			
		||||
          of the following places: within a NOTICE text file distributed
 | 
			
		||||
          as part of the Derivative Works; within the Source form or
 | 
			
		||||
          documentation, if provided along with the Derivative Works; or,
 | 
			
		||||
          within a display generated by the Derivative Works, if and
 | 
			
		||||
          wherever such third-party notices normally appear. The contents
 | 
			
		||||
          of the NOTICE file are for informational purposes only and
 | 
			
		||||
          do not modify the License. You may add Your own attribution
 | 
			
		||||
          notices within Derivative Works that You distribute, alongside
 | 
			
		||||
          or as an addendum to the NOTICE text from the Work, provided
 | 
			
		||||
          that such additional attribution notices cannot be construed
 | 
			
		||||
          as modifying the License.
 | 
			
		||||
 | 
			
		||||
      You may add Your own copyright statement to Your modifications and
 | 
			
		||||
      may provide additional or different license terms and conditions
 | 
			
		||||
      for use, reproduction, or distribution of Your modifications, or
 | 
			
		||||
      for any such Derivative Works as a whole, provided Your use,
 | 
			
		||||
      reproduction, and distribution of the Work otherwise complies with
 | 
			
		||||
      the conditions stated in this License.
 | 
			
		||||
 | 
			
		||||
   5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
			
		||||
      any Contribution intentionally submitted for inclusion in the Work
 | 
			
		||||
      by You to the Licensor shall be under the terms and conditions of
 | 
			
		||||
      this License, without any additional terms or conditions.
 | 
			
		||||
      Notwithstanding the above, nothing herein shall supersede or modify
 | 
			
		||||
      the terms of any separate license agreement you may have executed
 | 
			
		||||
      with Licensor regarding such Contributions.
 | 
			
		||||
 | 
			
		||||
   6. Trademarks. This License does not grant permission to use the trade
 | 
			
		||||
      names, trademarks, service marks, or product names of the Licensor,
 | 
			
		||||
      except as required for reasonable and customary use in describing the
 | 
			
		||||
      origin of the Work and reproducing the content of the NOTICE file.
 | 
			
		||||
 | 
			
		||||
   7. Disclaimer of Warranty. Unless required by applicable law or
 | 
			
		||||
      agreed to in writing, Licensor provides the Work (and each
 | 
			
		||||
      Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
			
		||||
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
			
		||||
      implied, including, without limitation, any warranties or conditions
 | 
			
		||||
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
			
		||||
      PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
			
		||||
      appropriateness of using or redistributing the Work and assume any
 | 
			
		||||
      risks associated with Your exercise of permissions under this License.
 | 
			
		||||
 | 
			
		||||
   8. Limitation of Liability. In no event and under no legal theory,
 | 
			
		||||
      whether in tort (including negligence), contract, or otherwise,
 | 
			
		||||
      unless required by applicable law (such as deliberate and grossly
 | 
			
		||||
      negligent acts) or agreed to in writing, shall any Contributor be
 | 
			
		||||
      liable to You for damages, including any direct, indirect, special,
 | 
			
		||||
      incidental, or consequential damages of any character arising as a
 | 
			
		||||
      result of this License or out of the use or inability to use the
 | 
			
		||||
      Work (including but not limited to damages for loss of goodwill,
 | 
			
		||||
      work stoppage, computer failure or malfunction, or any and all
 | 
			
		||||
      other commercial damages or losses), even if such Contributor
 | 
			
		||||
      has been advised of the possibility of such damages.
 | 
			
		||||
 | 
			
		||||
   9. Accepting Warranty or Additional Liability. While redistributing
 | 
			
		||||
      the Work or Derivative Works thereof, You may choose to offer,
 | 
			
		||||
      and charge a fee for, acceptance of support, warranty, indemnity,
 | 
			
		||||
      or other liability obligations and/or rights consistent with this
 | 
			
		||||
      License. However, in accepting such obligations, You may act only
 | 
			
		||||
      on Your own behalf and on Your sole responsibility, not on behalf
 | 
			
		||||
      of any other Contributor, and only if You agree to indemnify,
 | 
			
		||||
      defend, and hold each Contributor harmless for any liability
 | 
			
		||||
      incurred by, or claims asserted against, such Contributor by reason
 | 
			
		||||
      of your accepting any such warranty or additional liability.
 | 
			
		||||
 | 
			
		||||
   END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
   APPENDIX: How to apply the Apache License to your work.
 | 
			
		||||
 | 
			
		||||
      To apply the Apache License to your work, attach the following
 | 
			
		||||
      boilerplate notice, with the fields enclosed by brackets "[]"
 | 
			
		||||
      replaced with your own identifying information. (Don't include
 | 
			
		||||
      the brackets!)  The text should be enclosed in the appropriate
 | 
			
		||||
      comment syntax for the file format. We also recommend that a
 | 
			
		||||
      file or class name and description of purpose be included on the
 | 
			
		||||
      same "printed page" as the copyright notice for easier
 | 
			
		||||
      identification within third-party archives.
 | 
			
		||||
 | 
			
		||||
   Copyright [yyyy] [name of copyright owner]
 | 
			
		||||
 | 
			
		||||
   Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
   you may not use this file except in compliance with the License.
 | 
			
		||||
   You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
       http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
   Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
   distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
   See the License for the specific language governing permissions and
 | 
			
		||||
   limitations under the License.
 | 
			
		||||
							
								
								
									
										19
									
								
								server/node_modules/monk/node_modules/mongodb/node_modules/bson/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										19
									
								
								server/node_modules/monk/node_modules/mongodb/node_modules/bson/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
NODE = node
 | 
			
		||||
NPM = npm
 | 
			
		||||
NODEUNIT = node_modules/nodeunit/bin/nodeunit
 | 
			
		||||
 | 
			
		||||
all:	clean node_gyp
 | 
			
		||||
 | 
			
		||||
test: clean node_gyp
 | 
			
		||||
	npm test
 | 
			
		||||
 | 
			
		||||
node_gyp: clean
 | 
			
		||||
	node-gyp configure build
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
	node-gyp clean
 | 
			
		||||
 | 
			
		||||
browserify:
 | 
			
		||||
	node_modules/.bin/onejs build browser_build/package.json browser_build/bson.js
 | 
			
		||||
 | 
			
		||||
.PHONY: all
 | 
			
		||||
							
								
								
									
										69
									
								
								server/node_modules/monk/node_modules/mongodb/node_modules/bson/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										69
									
								
								server/node_modules/monk/node_modules/mongodb/node_modules/bson/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,69 @@
 | 
			
		||||
Javascript + C++ BSON parser
 | 
			
		||||
============================
 | 
			
		||||
 | 
			
		||||
This BSON parser is primarily meant to be used with the `mongodb` node.js driver.
 | 
			
		||||
However, wonderful tools such as `onejs` can package up a BSON parser that will work in the browser.
 | 
			
		||||
The current build is located in the `browser_build/bson.js` file.
 | 
			
		||||
 | 
			
		||||
A simple example of how to use BSON in the browser:
 | 
			
		||||
 | 
			
		||||
```html
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
  <script src="https://raw.github.com/mongodb/js-bson/master/browser_build/bson.js">
 | 
			
		||||
  </script>
 | 
			
		||||
</head>
 | 
			
		||||
<body onload="start();">
 | 
			
		||||
<script>
 | 
			
		||||
  function start() {
 | 
			
		||||
    var BSON = bson().BSON;
 | 
			
		||||
    var Long = bson().Long;
 | 
			
		||||
 | 
			
		||||
    var doc = {long: Long.fromNumber(100)}
 | 
			
		||||
 | 
			
		||||
    // Serialize a document
 | 
			
		||||
    var data = BSON.serialize(doc, false, true, false);
 | 
			
		||||
    // De serialize it again
 | 
			
		||||
    var doc_2 = BSON.deserialize(data);
 | 
			
		||||
  }
 | 
			
		||||
</script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
A simple example of how to use BSON in `node.js`:
 | 
			
		||||
 | 
			
		||||
```javascript
 | 
			
		||||
var bson = require("bson");
 | 
			
		||||
var BSON = bson.BSONPure.BSON;
 | 
			
		||||
var Long = bson.BSONPure.Long;
 | 
			
		||||
 | 
			
		||||
var doc = {long: Long.fromNumber(100)}
 | 
			
		||||
 | 
			
		||||
// Serialize a document
 | 
			
		||||
var data = BSON.serialize(doc, false, true, false);
 | 
			
		||||
console.log("data:", data);
 | 
			
		||||
 | 
			
		||||
// Deserialize the resulting Buffer
 | 
			
		||||
var doc_2 = BSON.deserialize(data);
 | 
			
		||||
console.log("doc_2:", doc_2);
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The API consists of two simple methods to serialize/deserialize objects to/from BSON format:
 | 
			
		||||
 | 
			
		||||
  * BSON.serialize(object, checkKeys, asBuffer, serializeFunctions)
 | 
			
		||||
     * @param {Object} object the Javascript object to serialize.
 | 
			
		||||
     * @param {Boolean} checkKeys the serializer will check if keys are valid.
 | 
			
		||||
     * @param {Boolean} asBuffer return the serialized object as a Buffer object **(ignore)**.
 | 
			
		||||
     * @param {Boolean} serializeFunctions serialize the javascript functions **(default:false)**
 | 
			
		||||
     * @return {TypedArray/Array} returns a TypedArray or Array depending on what your browser supports
 | 
			
		||||
 
 | 
			
		||||
  * BSON.deserialize(buffer, options, isArray)
 | 
			
		||||
     * Options
 | 
			
		||||
       * **evalFunctions** {Boolean, default:false}, evaluate functions in the BSON document scoped to the object deserialized.
 | 
			
		||||
       * **cacheFunctions** {Boolean, default:false}, cache evaluated functions for reuse.
 | 
			
		||||
       * **cacheFunctionsCrc32** {Boolean, default:false}, use a crc32 code for caching, otherwise use the string of the function.
 | 
			
		||||
     * @param {TypedArray/Array} a TypedArray/Array containing the BSON data
 | 
			
		||||
     * @param {Object} [options] additional options used for the deserialization.
 | 
			
		||||
     * @param {Boolean} [isArray] ignore used for recursive parsing.
 | 
			
		||||
     * @return {Object} returns the deserialized Javascript Object.
 | 
			
		||||
							
								
								
									
										18
									
								
								server/node_modules/monk/node_modules/mongodb/node_modules/bson/binding.gyp
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										18
									
								
								server/node_modules/monk/node_modules/mongodb/node_modules/bson/binding.gyp
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
{
 | 
			
		||||
  'targets': [
 | 
			
		||||
    {
 | 
			
		||||
      'target_name': 'bson',
 | 
			
		||||
      'sources': [ 'ext/bson.cc' ],
 | 
			
		||||
      'cflags!': [ '-fno-exceptions' ],
 | 
			
		||||
      'cflags_cc!': [ '-fno-exceptions' ],
 | 
			
		||||
      'include_dirs': [ '<!(node -e "require(\'nan\')")' ],
 | 
			
		||||
      'conditions': [
 | 
			
		||||
        ['OS=="mac"', {
 | 
			
		||||
          'xcode_settings': {
 | 
			
		||||
            'GCC_ENABLE_CPP_EXCEPTIONS': 'YES'
 | 
			
		||||
          }
 | 
			
		||||
        }]
 | 
			
		||||
      ]
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4843
									
								
								server/node_modules/monk/node_modules/mongodb/node_modules/bson/browser_build/bson.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										4843
									
								
								server/node_modules/monk/node_modules/mongodb/node_modules/bson/browser_build/bson.js
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										8
									
								
								server/node_modules/monk/node_modules/mongodb/node_modules/bson/browser_build/package.json
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										8
									
								
								server/node_modules/monk/node_modules/mongodb/node_modules/bson/browser_build/package.json
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
{ "name" :            "bson"
 | 
			
		||||
, "description" :     "A bson parser for node.js and the browser"
 | 
			
		||||
, "main":             "../lib/bson/bson"
 | 
			
		||||
, "directories" :   { "lib" : "../lib/bson" }
 | 
			
		||||
, "engines" :       { "node" : ">=0.6.0" }
 | 
			
		||||
, "licenses" :    [ { "type" :  "Apache License, Version 2.0"
 | 
			
		||||
                    , "url" :   "http://www.apache.org/licenses/LICENSE-2.0" } ]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										332
									
								
								server/node_modules/monk/node_modules/mongodb/node_modules/bson/build/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										332
									
								
								server/node_modules/monk/node_modules/mongodb/node_modules/bson/build/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,332 @@
 | 
			
		||||
# We borrow heavily from the kernel build setup, though we are simpler since
 | 
			
		||||
# we don't have Kconfig tweaking settings on us.
 | 
			
		||||
 | 
			
		||||
# The implicit make rules have it looking for RCS files, among other things.
 | 
			
		||||
# We instead explicitly write all the rules we care about.
 | 
			
		||||
# It's even quicker (saves ~200ms) to pass -r on the command line.
 | 
			
		||||
MAKEFLAGS=-r
 | 
			
		||||
 | 
			
		||||
# The source directory tree.
 | 
			
		||||
srcdir := ..
 | 
			
		||||
abs_srcdir := $(abspath $(srcdir))
 | 
			
		||||
 | 
			
		||||
# The name of the builddir.
 | 
			
		||||
builddir_name ?= .
 | 
			
		||||
 | 
			
		||||
# The V=1 flag on command line makes us verbosely print command lines.
 | 
			
		||||
ifdef V
 | 
			
		||||
  quiet=
 | 
			
		||||
else
 | 
			
		||||
  quiet=quiet_
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
# Specify BUILDTYPE=Release on the command line for a release build.
 | 
			
		||||
BUILDTYPE ?= Release
 | 
			
		||||
 | 
			
		||||
# Directory all our build output goes into.
 | 
			
		||||
# Note that this must be two directories beneath src/ for unit tests to pass,
 | 
			
		||||
# as they reach into the src/ directory for data with relative paths.
 | 
			
		||||
builddir ?= $(builddir_name)/$(BUILDTYPE)
 | 
			
		||||
abs_builddir := $(abspath $(builddir))
 | 
			
		||||
depsdir := $(builddir)/.deps
 | 
			
		||||
 | 
			
		||||
# Object output directory.
 | 
			
		||||
obj := $(builddir)/obj
 | 
			
		||||
abs_obj := $(abspath $(obj))
 | 
			
		||||
 | 
			
		||||
# We build up a list of every single one of the targets so we can slurp in the
 | 
			
		||||
# generated dependency rule Makefiles in one pass.
 | 
			
		||||
all_deps :=
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CC.target ?= $(CC)
 | 
			
		||||
CFLAGS.target ?= $(CFLAGS)
 | 
			
		||||
CXX.target ?= $(CXX)
 | 
			
		||||
CXXFLAGS.target ?= $(CXXFLAGS)
 | 
			
		||||
LINK.target ?= $(LINK)
 | 
			
		||||
LDFLAGS.target ?= $(LDFLAGS)
 | 
			
		||||
AR.target ?= $(AR)
 | 
			
		||||
 | 
			
		||||
# C++ apps need to be linked with g++.
 | 
			
		||||
#
 | 
			
		||||
# Note: flock is used to seralize linking. Linking is a memory-intensive
 | 
			
		||||
# process so running parallel links can often lead to thrashing.  To disable
 | 
			
		||||
# the serialization, override LINK via an envrionment variable as follows:
 | 
			
		||||
#
 | 
			
		||||
#   export LINK=g++
 | 
			
		||||
#
 | 
			
		||||
# This will allow make to invoke N linker processes as specified in -jN.
 | 
			
		||||
LINK ?= flock $(builddir)/linker.lock $(CXX.target)
 | 
			
		||||
 | 
			
		||||
# TODO(evan): move all cross-compilation logic to gyp-time so we don't need
 | 
			
		||||
# to replicate this environment fallback in make as well.
 | 
			
		||||
CC.host ?= gcc
 | 
			
		||||
CFLAGS.host ?=
 | 
			
		||||
CXX.host ?= g++
 | 
			
		||||
CXXFLAGS.host ?=
 | 
			
		||||
LINK.host ?= $(CXX.host)
 | 
			
		||||
LDFLAGS.host ?=
 | 
			
		||||
AR.host ?= ar
 | 
			
		||||
 | 
			
		||||
# Define a dir function that can handle spaces.
 | 
			
		||||
# http://www.gnu.org/software/make/manual/make.html#Syntax-of-Functions
 | 
			
		||||
# "leading spaces cannot appear in the text of the first argument as written.
 | 
			
		||||
# These characters can be put into the argument value by variable substitution."
 | 
			
		||||
empty :=
 | 
			
		||||
space := $(empty) $(empty)
 | 
			
		||||
 | 
			
		||||
# http://stackoverflow.com/questions/1189781/using-make-dir-or-notdir-on-a-path-with-spaces
 | 
			
		||||
replace_spaces = $(subst $(space),?,$1)
 | 
			
		||||
unreplace_spaces = $(subst ?,$(space),$1)
 | 
			
		||||
dirx = $(call unreplace_spaces,$(dir $(call replace_spaces,$1)))
 | 
			
		||||
 | 
			
		||||
# Flags to make gcc output dependency info.  Note that you need to be
 | 
			
		||||
# careful here to use the flags that ccache and distcc can understand.
 | 
			
		||||
# We write to a dep file on the side first and then rename at the end
 | 
			
		||||
# so we can't end up with a broken dep file.
 | 
			
		||||
depfile = $(depsdir)/$(call replace_spaces,$@).d
 | 
			
		||||
DEPFLAGS = -MMD -MF $(depfile).raw
 | 
			
		||||
 | 
			
		||||
# We have to fixup the deps output in a few ways.
 | 
			
		||||
# (1) the file output should mention the proper .o file.
 | 
			
		||||
# ccache or distcc lose the path to the target, so we convert a rule of
 | 
			
		||||
# the form:
 | 
			
		||||
#   foobar.o: DEP1 DEP2
 | 
			
		||||
# into
 | 
			
		||||
#   path/to/foobar.o: DEP1 DEP2
 | 
			
		||||
# (2) we want missing files not to cause us to fail to build.
 | 
			
		||||
# We want to rewrite
 | 
			
		||||
#   foobar.o: DEP1 DEP2 \
 | 
			
		||||
#               DEP3
 | 
			
		||||
# to
 | 
			
		||||
#   DEP1:
 | 
			
		||||
#   DEP2:
 | 
			
		||||
#   DEP3:
 | 
			
		||||
# so if the files are missing, they're just considered phony rules.
 | 
			
		||||
# We have to do some pretty insane escaping to get those backslashes
 | 
			
		||||
# and dollar signs past make, the shell, and sed at the same time.
 | 
			
		||||
# Doesn't work with spaces, but that's fine: .d files have spaces in
 | 
			
		||||
# their names replaced with other characters.
 | 
			
		||||
define fixup_dep
 | 
			
		||||
# The depfile may not exist if the input file didn't have any #includes.
 | 
			
		||||
touch $(depfile).raw
 | 
			
		||||
# Fixup path as in (1).
 | 
			
		||||
sed -e "s|^$(notdir $@)|$@|" $(depfile).raw >> $(depfile)
 | 
			
		||||
# Add extra rules as in (2).
 | 
			
		||||
# We remove slashes and replace spaces with new lines;
 | 
			
		||||
# remove blank lines;
 | 
			
		||||
# delete the first line and append a colon to the remaining lines.
 | 
			
		||||
sed -e 's|\\||' -e 'y| |\n|' $(depfile).raw |\
 | 
			
		||||
  grep -v '^$$'                             |\
 | 
			
		||||
  sed -e 1d -e 's|$$|:|'                     \
 | 
			
		||||
    >> $(depfile)
 | 
			
		||||
rm $(depfile).raw
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
# Command definitions:
 | 
			
		||||
# - cmd_foo is the actual command to run;
 | 
			
		||||
# - quiet_cmd_foo is the brief-output summary of the command.
 | 
			
		||||
 | 
			
		||||
quiet_cmd_cc = CC($(TOOLSET)) $@
 | 
			
		||||
cmd_cc = $(CC.$(TOOLSET)) $(GYP_CFLAGS) $(DEPFLAGS) $(CFLAGS.$(TOOLSET)) -c -o $@ $<
 | 
			
		||||
 | 
			
		||||
quiet_cmd_cxx = CXX($(TOOLSET)) $@
 | 
			
		||||
cmd_cxx = $(CXX.$(TOOLSET)) $(GYP_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $<
 | 
			
		||||
 | 
			
		||||
quiet_cmd_touch = TOUCH $@
 | 
			
		||||
cmd_touch = touch $@
 | 
			
		||||
 | 
			
		||||
quiet_cmd_copy = COPY $@
 | 
			
		||||
# send stderr to /dev/null to ignore messages when linking directories.
 | 
			
		||||
cmd_copy = rm -rf "$@" && cp -af "$<" "$@"
 | 
			
		||||
 | 
			
		||||
quiet_cmd_alink = AR($(TOOLSET)) $@
 | 
			
		||||
cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) crs $@ $(filter %.o,$^)
 | 
			
		||||
 | 
			
		||||
quiet_cmd_alink_thin = AR($(TOOLSET)) $@
 | 
			
		||||
cmd_alink_thin = rm -f $@ && $(AR.$(TOOLSET)) crsT $@ $(filter %.o,$^)
 | 
			
		||||
 | 
			
		||||
# Due to circular dependencies between libraries :(, we wrap the
 | 
			
		||||
# special "figure out circular dependencies" flags around the entire
 | 
			
		||||
# input list during linking.
 | 
			
		||||
quiet_cmd_link = LINK($(TOOLSET)) $@
 | 
			
		||||
cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--start-group $(LD_INPUTS) -Wl,--end-group $(LIBS)
 | 
			
		||||
 | 
			
		||||
# We support two kinds of shared objects (.so):
 | 
			
		||||
# 1) shared_library, which is just bundling together many dependent libraries
 | 
			
		||||
# into a link line.
 | 
			
		||||
# 2) loadable_module, which is generating a module intended for dlopen().
 | 
			
		||||
#
 | 
			
		||||
# They differ only slightly:
 | 
			
		||||
# In the former case, we want to package all dependent code into the .so.
 | 
			
		||||
# In the latter case, we want to package just the API exposed by the
 | 
			
		||||
# outermost module.
 | 
			
		||||
# This means shared_library uses --whole-archive, while loadable_module doesn't.
 | 
			
		||||
# (Note that --whole-archive is incompatible with the --start-group used in
 | 
			
		||||
# normal linking.)
 | 
			
		||||
 | 
			
		||||
# Other shared-object link notes:
 | 
			
		||||
# - Set SONAME to the library filename so our binaries don't reference
 | 
			
		||||
# the local, absolute paths used on the link command-line.
 | 
			
		||||
quiet_cmd_solink = SOLINK($(TOOLSET)) $@
 | 
			
		||||
cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--whole-archive $(LD_INPUTS) -Wl,--no-whole-archive $(LIBS)
 | 
			
		||||
 | 
			
		||||
quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@
 | 
			
		||||
cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--start-group $(filter-out FORCE_DO_CMD, $^) -Wl,--end-group $(LIBS)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Define an escape_quotes function to escape single quotes.
 | 
			
		||||
# This allows us to handle quotes properly as long as we always use
 | 
			
		||||
# use single quotes and escape_quotes.
 | 
			
		||||
escape_quotes = $(subst ','\'',$(1))
 | 
			
		||||
# This comment is here just to include a ' to unconfuse syntax highlighting.
 | 
			
		||||
# Define an escape_vars function to escape '$' variable syntax.
 | 
			
		||||
# This allows us to read/write command lines with shell variables (e.g.
 | 
			
		||||
# $LD_LIBRARY_PATH), without triggering make substitution.
 | 
			
		||||
escape_vars = $(subst $$,$$$$,$(1))
 | 
			
		||||
# Helper that expands to a shell command to echo a string exactly as it is in
 | 
			
		||||
# make. This uses printf instead of echo because printf's behaviour with respect
 | 
			
		||||
# to escape sequences is more portable than echo's across different shells
 | 
			
		||||
# (e.g., dash, bash).
 | 
			
		||||
exact_echo = printf '%s\n' '$(call escape_quotes,$(1))'
 | 
			
		||||
 | 
			
		||||
# Helper to compare the command we're about to run against the command
 | 
			
		||||
# we logged the last time we ran the command.  Produces an empty
 | 
			
		||||
# string (false) when the commands match.
 | 
			
		||||
# Tricky point: Make has no string-equality test function.
 | 
			
		||||
# The kernel uses the following, but it seems like it would have false
 | 
			
		||||
# positives, where one string reordered its arguments.
 | 
			
		||||
#   arg_check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \
 | 
			
		||||
#                       $(filter-out $(cmd_$@), $(cmd_$(1))))
 | 
			
		||||
# We instead substitute each for the empty string into the other, and
 | 
			
		||||
# say they're equal if both substitutions produce the empty string.
 | 
			
		||||
# .d files contain ? instead of spaces, take that into account.
 | 
			
		||||
command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$(call replace_spaces,$@))),\
 | 
			
		||||
                       $(subst $(cmd_$(call replace_spaces,$@)),,$(cmd_$(1))))
 | 
			
		||||
 | 
			
		||||
# Helper that is non-empty when a prerequisite changes.
 | 
			
		||||
# Normally make does this implicitly, but we force rules to always run
 | 
			
		||||
# so we can check their command lines.
 | 
			
		||||
#   $? -- new prerequisites
 | 
			
		||||
#   $| -- order-only dependencies
 | 
			
		||||
prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?))
 | 
			
		||||
 | 
			
		||||
# Helper that executes all postbuilds until one fails.
 | 
			
		||||
define do_postbuilds
 | 
			
		||||
  @E=0;\
 | 
			
		||||
  for p in $(POSTBUILDS); do\
 | 
			
		||||
    eval $$p;\
 | 
			
		||||
    E=$$?;\
 | 
			
		||||
    if [ $$E -ne 0 ]; then\
 | 
			
		||||
      break;\
 | 
			
		||||
    fi;\
 | 
			
		||||
  done;\
 | 
			
		||||
  if [ $$E -ne 0 ]; then\
 | 
			
		||||
    rm -rf "$@";\
 | 
			
		||||
    exit $$E;\
 | 
			
		||||
  fi
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
# do_cmd: run a command via the above cmd_foo names, if necessary.
 | 
			
		||||
# Should always run for a given target to handle command-line changes.
 | 
			
		||||
# Second argument, if non-zero, makes it do asm/C/C++ dependency munging.
 | 
			
		||||
# Third argument, if non-zero, makes it do POSTBUILDS processing.
 | 
			
		||||
# Note: We intentionally do NOT call dirx for depfile, since it contains ? for
 | 
			
		||||
# spaces already and dirx strips the ? characters.
 | 
			
		||||
define do_cmd
 | 
			
		||||
$(if $(or $(command_changed),$(prereq_changed)),
 | 
			
		||||
  @$(call exact_echo,  $($(quiet)cmd_$(1)))
 | 
			
		||||
  @mkdir -p "$(call dirx,$@)" "$(dir $(depfile))"
 | 
			
		||||
  $(if $(findstring flock,$(word 1,$(cmd_$1))),
 | 
			
		||||
    @$(cmd_$(1))
 | 
			
		||||
    @echo "  $(quiet_cmd_$(1)): Finished",
 | 
			
		||||
    @$(cmd_$(1))
 | 
			
		||||
  )
 | 
			
		||||
  @$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile)
 | 
			
		||||
  @$(if $(2),$(fixup_dep))
 | 
			
		||||
  $(if $(and $(3), $(POSTBUILDS)),
 | 
			
		||||
    $(call do_postbuilds)
 | 
			
		||||
  )
 | 
			
		||||
)
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
# Declare the "all" target first so it is the default,
 | 
			
		||||
# even though we don't have the deps yet.
 | 
			
		||||
.PHONY: all
 | 
			
		||||
all:
 | 
			
		||||
 | 
			
		||||
# make looks for ways to re-generate included makefiles, but in our case, we
 | 
			
		||||
# don't have a direct way. Explicitly telling make that it has nothing to do
 | 
			
		||||
# for them makes it go faster.
 | 
			
		||||
%.d: ;
 | 
			
		||||
 | 
			
		||||
# Use FORCE_DO_CMD to force a target to run.  Should be coupled with
 | 
			
		||||
# do_cmd.
 | 
			
		||||
.PHONY: FORCE_DO_CMD
 | 
			
		||||
FORCE_DO_CMD:
 | 
			
		||||
 | 
			
		||||
TOOLSET := target
 | 
			
		||||
# Suffix rules, putting all outputs into $(obj).
 | 
			
		||||
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.c FORCE_DO_CMD
 | 
			
		||||
	@$(call do_cmd,cc,1)
 | 
			
		||||
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD
 | 
			
		||||
	@$(call do_cmd,cxx,1)
 | 
			
		||||
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cpp FORCE_DO_CMD
 | 
			
		||||
	@$(call do_cmd,cxx,1)
 | 
			
		||||
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cxx FORCE_DO_CMD
 | 
			
		||||
	@$(call do_cmd,cxx,1)
 | 
			
		||||
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.S FORCE_DO_CMD
 | 
			
		||||
	@$(call do_cmd,cc,1)
 | 
			
		||||
$(obj).$(TOOLSET)/%.o: $(srcdir)/%.s FORCE_DO_CMD
 | 
			
		||||
	@$(call do_cmd,cc,1)
 | 
			
		||||
 | 
			
		||||
# Try building from generated source, too.
 | 
			
		||||
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD
 | 
			
		||||
	@$(call do_cmd,cc,1)
 | 
			
		||||
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD
 | 
			
		||||
	@$(call do_cmd,cxx,1)
 | 
			
		||||
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cpp FORCE_DO_CMD
 | 
			
		||||
	@$(call do_cmd,cxx,1)
 | 
			
		||||
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cxx FORCE_DO_CMD
 | 
			
		||||
	@$(call do_cmd,cxx,1)
 | 
			
		||||
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.S FORCE_DO_CMD
 | 
			
		||||
	@$(call do_cmd,cc,1)
 | 
			
		||||
$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.s FORCE_DO_CMD
 | 
			
		||||
	@$(call do_cmd,cc,1)
 | 
			
		||||
 | 
			
		||||
$(obj).$(TOOLSET)/%.o: $(obj)/%.c FORCE_DO_CMD
 | 
			
		||||
	@$(call do_cmd,cc,1)
 | 
			
		||||
$(obj).$(TOOLSET)/%.o: $(obj)/%.cc FORCE_DO_CMD
 | 
			
		||||
	@$(call do_cmd,cxx,1)
 | 
			
		||||
$(obj).$(TOOLSET)/%.o: $(obj)/%.cpp FORCE_DO_CMD
 | 
			
		||||
	@$(call do_cmd,cxx,1)
 | 
			
		||||
$(obj).$(TOOLSET)/%.o: $(obj)/%.cxx FORCE_DO_CMD
 | 
			
		||||
	@$(call do_cmd,cxx,1)
 | 
			
		||||
$(obj).$(TOOLSET)/%.o: $(obj)/%.S FORCE_DO_CMD
 | 
			
		||||
	@$(call do_cmd,cc,1)
 | 
			
		||||
$(obj).$(TOOLSET)/%.o: $(obj)/%.s FORCE_DO_CMD
 | 
			
		||||
	@$(call do_cmd,cc,1)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ifeq ($(strip $(foreach prefix,$(NO_LOAD),\
 | 
			
		||||
    $(findstring $(join ^,$(prefix)),\
 | 
			
		||||
                 $(join ^,bson.target.mk)))),)
 | 
			
		||||
  include bson.target.mk
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
quiet_cmd_regen_makefile = ACTION Regenerating $@
 | 
			
		||||
cmd_regen_makefile = cd $(srcdir); /usr/lib/node_modules/npm/node_modules/node-gyp/gyp/gyp_main.py -fmake --ignore-environment "--toplevel-dir=." -I/var/www/server/node_modules/monk/node_modules/mongodb/node_modules/bson/build/config.gypi -I/usr/lib/node_modules/npm/node_modules/node-gyp/addon.gypi -I/home/kasperrt/.node-gyp/0.10.33/common.gypi "--depth=." "-Goutput_dir=." "--generator-output=build" "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/home/kasperrt/.node-gyp/0.10.33" "-Dmodule_root_dir=/var/www/server/node_modules/monk/node_modules/mongodb/node_modules/bson" binding.gyp
 | 
			
		||||
Makefile: $(srcdir)/../../../../../../../../../home/kasperrt/.node-gyp/0.10.33/common.gypi $(srcdir)/build/config.gypi $(srcdir)/binding.gyp $(srcdir)/../../../../../../../../../usr/lib/node_modules/npm/node_modules/node-gyp/addon.gypi
 | 
			
		||||
	$(call do_cmd,regen_makefile)
 | 
			
		||||
 | 
			
		||||
# "all" is a concatenation of the "all" targets from all the included
 | 
			
		||||
# sub-makefiles. This is just here to clarify.
 | 
			
		||||
all:
 | 
			
		||||
 | 
			
		||||
# Add in dependency-tracking rules.  $(all_deps) is the list of every single
 | 
			
		||||
# target in our tree. Only consider the ones with .d (dependency) info:
 | 
			
		||||
d_files := $(wildcard $(foreach f,$(all_deps),$(depsdir)/$(f).d))
 | 
			
		||||
ifneq ($(d_files),)
 | 
			
		||||
  include $(d_files)
 | 
			
		||||
endif
 | 
			
		||||
							
								
								
									
										1
									
								
								server/node_modules/monk/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/bson.node.d
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										1
									
								
								server/node_modules/monk/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/bson.node.d
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
cmd_Release/bson.node := rm -rf "Release/bson.node" && cp -af "Release/obj.target/bson.node" "Release/bson.node"
 | 
			
		||||
							
								
								
									
										1
									
								
								server/node_modules/monk/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/obj.target/bson.node.d
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										1
									
								
								server/node_modules/monk/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/obj.target/bson.node.d
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
cmd_Release/obj.target/bson.node := flock ./Release/linker.lock g++ -shared -pthread -rdynamic -m64  -Wl,-soname=bson.node -o Release/obj.target/bson.node -Wl,--start-group Release/obj.target/bson/ext/bson.o -Wl,--end-group 
 | 
			
		||||
							
								
								
									
										33
									
								
								server/node_modules/monk/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/obj.target/bson/ext/bson.o.d
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										33
									
								
								server/node_modules/monk/node_modules/mongodb/node_modules/bson/build/Release/.deps/Release/obj.target/bson/ext/bson.o.d
									
									
									
										generated
									
									
										vendored
									
									
										Executable file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
cmd_Release/obj.target/bson/ext/bson.o := g++ '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/home/kasperrt/.node-gyp/0.10.33/src -I/home/kasperrt/.node-gyp/0.10.33/deps/uv/include -I/home/kasperrt/.node-gyp/0.10.33/deps/v8/include -I../node_modules/nan  -fPIC -Wall -Wextra -Wno-unused-parameter -pthread -m64 -O2 -fno-strict-aliasing -fno-tree-vrp -fno-omit-frame-pointer -fno-rtti -MMD -MF ./Release/.deps/Release/obj.target/bson/ext/bson.o.d.raw  -c -o Release/obj.target/bson/ext/bson.o ../ext/bson.cc
 | 
			
		||||
Release/obj.target/bson/ext/bson.o: ../ext/bson.cc \
 | 
			
		||||
 /home/kasperrt/.node-gyp/0.10.33/deps/v8/include/v8.h \
 | 
			
		||||
 /home/kasperrt/.node-gyp/0.10.33/deps/v8/include/v8stdint.h \
 | 
			
		||||
 /home/kasperrt/.node-gyp/0.10.33/src/node.h \
 | 
			
		||||
 /home/kasperrt/.node-gyp/0.10.33/deps/uv/include/uv.h \
 | 
			
		||||
 /home/kasperrt/.node-gyp/0.10.33/deps/uv/include/uv-private/uv-unix.h \
 | 
			
		||||
 /home/kasperrt/.node-gyp/0.10.33/deps/uv/include/uv-private/ngx-queue.h \
 | 
			
		||||
 /home/kasperrt/.node-gyp/0.10.33/deps/uv/include/uv-private/uv-linux.h \
 | 
			
		||||
 /home/kasperrt/.node-gyp/0.10.33/src/node_object_wrap.h \
 | 
			
		||||
 /home/kasperrt/.node-gyp/0.10.33/src/node.h \
 | 
			
		||||
 /home/kasperrt/.node-gyp/0.10.33/src/node_version.h \
 | 
			
		||||
 /home/kasperrt/.node-gyp/0.10.33/src/node_buffer.h ../ext/bson.h \
 | 
			
		||||
 /home/kasperrt/.node-gyp/0.10.33/src/node_object_wrap.h \
 | 
			
		||||
 ../node_modules/nan/nan.h ../node_modules/nan/nan_new.h \
 | 
			
		||||
 ../node_modules/nan/nan_implementation_pre_12_inl.h
 | 
			
		||||
../ext/bson.cc:
 | 
			
		||||
/home/kasperrt/.node-gyp/0.10.33/deps/v8/include/v8.h:
 | 
			
		||||
/home/kasperrt/.node-gyp/0.10.33/deps/v8/include/v8stdint.h:
 | 
			
		||||
/home/kasperrt/.node-gyp/0.10.33/src/node.h:
 | 
			
		||||
/home/kasperrt/.node-gyp/0.10.33/deps/uv/include/uv.h:
 | 
			
		||||
/home/kasperrt/.node-gyp/0.10.33/deps/uv/include/uv-private/uv-unix.h:
 | 
			
		||||
/home/kasperrt/.node-gyp/0.10.33/deps/uv/include/uv-private/ngx-queue.h:
 | 
			
		||||
/home/kasperrt/.node-gyp/0.10.33/deps/uv/include/uv-private/uv-linux.h:
 | 
			
		||||
/home/kasperrt/.node-gyp/0.10.33/src/node_object_wrap.h:
 | 
			
		||||
/home/kasperrt/.node-gyp/0.10.33/src/node.h:
 | 
			
		||||
/home/kasperrt/.node-gyp/0.10.33/src/node_version.h:
 | 
			
		||||
/home/kasperrt/.node-gyp/0.10.33/src/node_buffer.h:
 | 
			
		||||
../ext/bson.h:
 | 
			
		||||
/home/kasperrt/.node-gyp/0.10.33/src/node_object_wrap.h:
 | 
			
		||||
../node_modules/nan/nan.h:
 | 
			
		||||
../node_modules/nan/nan_new.h:
 | 
			
		||||
../node_modules/nan/nan_implementation_pre_12_inl.h:
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user