mongodb 3.2.5 → 3.3.0-beta2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/HISTORY.md +0 -10
- package/index.js +4 -4
- package/lib/admin.js +56 -56
- package/lib/aggregation_cursor.js +7 -3
- package/lib/bulk/common.js +18 -13
- package/lib/change_stream.js +196 -89
- package/lib/collection.js +217 -169
- package/lib/command_cursor.js +17 -7
- package/lib/core/auth/auth_provider.js +158 -0
- package/lib/core/auth/defaultAuthProviders.js +29 -0
- package/lib/core/auth/gssapi.js +241 -0
- package/lib/core/auth/mongo_credentials.js +81 -0
- package/lib/core/auth/mongocr.js +51 -0
- package/lib/core/auth/plain.js +35 -0
- package/lib/core/auth/scram.js +293 -0
- package/lib/core/auth/sspi.js +131 -0
- package/lib/core/auth/x509.js +26 -0
- package/lib/core/connection/apm.js +236 -0
- package/lib/core/connection/command_result.js +36 -0
- package/lib/core/connection/commands.js +507 -0
- package/lib/core/connection/connect.js +370 -0
- package/lib/core/connection/connection.js +624 -0
- package/lib/core/connection/logger.js +246 -0
- package/lib/core/connection/msg.js +219 -0
- package/lib/core/connection/pool.js +1285 -0
- package/lib/core/connection/utils.js +57 -0
- package/lib/core/cursor.js +752 -0
- package/lib/core/error.js +186 -0
- package/lib/core/index.js +50 -0
- package/lib/core/sdam/monitoring.js +228 -0
- package/lib/core/sdam/server.js +467 -0
- package/lib/core/sdam/server_description.js +163 -0
- package/lib/core/sdam/server_selectors.js +244 -0
- package/lib/core/sdam/srv_polling.js +135 -0
- package/lib/core/sdam/topology.js +1151 -0
- package/lib/core/sdam/topology_description.js +408 -0
- package/lib/core/sessions.js +711 -0
- package/lib/core/tools/smoke_plugin.js +61 -0
- package/lib/core/topologies/mongos.js +1337 -0
- package/lib/core/topologies/read_preference.js +202 -0
- package/lib/core/topologies/replset.js +1507 -0
- package/lib/core/topologies/replset_state.js +1121 -0
- package/lib/core/topologies/server.js +984 -0
- package/lib/core/topologies/shared.js +453 -0
- package/lib/core/transactions.js +167 -0
- package/lib/core/uri_parser.js +631 -0
- package/lib/core/utils.js +165 -0
- package/lib/core/wireprotocol/command.js +170 -0
- package/lib/core/wireprotocol/compression.js +73 -0
- package/lib/core/wireprotocol/constants.js +13 -0
- package/lib/core/wireprotocol/get_more.js +86 -0
- package/lib/core/wireprotocol/index.js +18 -0
- package/lib/core/wireprotocol/kill_cursors.js +70 -0
- package/lib/core/wireprotocol/query.js +224 -0
- package/lib/core/wireprotocol/shared.js +115 -0
- package/lib/core/wireprotocol/write_command.js +50 -0
- package/lib/cursor.js +40 -46
- package/lib/db.js +141 -95
- package/lib/dynamic_loaders.js +32 -0
- package/lib/error.js +12 -10
- package/lib/gridfs/chunk.js +2 -2
- package/lib/gridfs/grid_store.js +31 -25
- package/lib/gridfs-stream/index.js +4 -4
- package/lib/gridfs-stream/upload.js +1 -1
- package/lib/mongo_client.js +37 -15
- package/lib/operations/add_user.js +96 -0
- package/lib/operations/aggregate.js +24 -13
- package/lib/operations/aggregate_operation.js +127 -0
- package/lib/operations/bulk_write.js +104 -0
- package/lib/operations/close.js +47 -0
- package/lib/operations/collection_ops.js +28 -287
- package/lib/operations/collections.js +55 -0
- package/lib/operations/command.js +120 -0
- package/lib/operations/command_v2.js +43 -0
- package/lib/operations/common_functions.js +372 -0
- package/lib/operations/{mongo_client_ops.js → connect.js} +185 -157
- package/lib/operations/count.js +72 -0
- package/lib/operations/count_documents.js +46 -0
- package/lib/operations/create_collection.js +118 -0
- package/lib/operations/create_index.js +92 -0
- package/lib/operations/create_indexes.js +61 -0
- package/lib/operations/cursor_ops.js +3 -4
- package/lib/operations/db_ops.js +15 -12
- package/lib/operations/delete_many.js +25 -0
- package/lib/operations/delete_one.js +25 -0
- package/lib/operations/distinct.js +85 -0
- package/lib/operations/drop.js +53 -0
- package/lib/operations/drop_index.js +42 -0
- package/lib/operations/drop_indexes.js +23 -0
- package/lib/operations/estimated_document_count.js +33 -0
- package/lib/operations/execute_db_admin_command.js +34 -0
- package/lib/operations/execute_operation.js +165 -0
- package/lib/operations/explain.js +23 -0
- package/lib/operations/find_and_modify.js +98 -0
- package/lib/operations/find_one.js +33 -0
- package/lib/operations/find_one_and_delete.js +16 -0
- package/lib/operations/find_one_and_replace.js +18 -0
- package/lib/operations/find_one_and_update.js +19 -0
- package/lib/operations/geo_haystack_search.js +79 -0
- package/lib/operations/has_next.js +40 -0
- package/lib/operations/index_exists.js +39 -0
- package/lib/operations/index_information.js +23 -0
- package/lib/operations/indexes.js +22 -0
- package/lib/operations/insert_many.js +63 -0
- package/lib/operations/insert_one.js +75 -0
- package/lib/operations/is_capped.js +19 -0
- package/lib/operations/list_indexes.js +66 -0
- package/lib/operations/map_reduce.js +189 -0
- package/lib/operations/next.js +32 -0
- package/lib/operations/operation.js +63 -0
- package/lib/operations/options_operation.js +32 -0
- package/lib/operations/profiling_level.js +31 -0
- package/lib/operations/re_index.js +28 -0
- package/lib/operations/remove_user.js +52 -0
- package/lib/operations/rename.js +61 -0
- package/lib/operations/replace_one.js +47 -0
- package/lib/operations/set_profiling_level.js +48 -0
- package/lib/operations/stats.js +45 -0
- package/lib/operations/to_array.js +68 -0
- package/lib/operations/update_many.js +29 -0
- package/lib/operations/update_one.js +44 -0
- package/lib/operations/validate_collection.js +40 -0
- package/lib/read_concern.js +55 -0
- package/lib/topologies/mongos.js +3 -3
- package/lib/topologies/native_topology.js +22 -2
- package/lib/topologies/replset.js +3 -3
- package/lib/topologies/server.js +4 -4
- package/lib/topologies/topology_base.js +6 -6
- package/lib/url_parser.js +4 -3
- package/lib/utils.js +46 -59
- package/lib/write_concern.js +66 -0
- package/package.json +15 -6
- package/lib/.DS_Store +0 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const applyRetryableWrites = require('../utils').applyRetryableWrites;
|
|
4
|
+
const applyWriteConcern = require('../utils').applyWriteConcern;
|
|
5
|
+
const handleCallback = require('../utils').handleCallback;
|
|
6
|
+
const MongoError = require('../core').MongoError;
|
|
7
|
+
const OperationBase = require('./operation').OperationBase;
|
|
8
|
+
const prepareDocs = require('./common_functions').prepareDocs;
|
|
9
|
+
const toError = require('../utils').toError;
|
|
10
|
+
|
|
11
|
+
class InsertOneOperation extends OperationBase {
|
|
12
|
+
constructor(collection, doc, options) {
|
|
13
|
+
super(options);
|
|
14
|
+
|
|
15
|
+
this.collection = collection;
|
|
16
|
+
this.doc = doc;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
execute(callback) {
|
|
20
|
+
const coll = this.collection;
|
|
21
|
+
const doc = this.doc;
|
|
22
|
+
const options = this.options;
|
|
23
|
+
|
|
24
|
+
if (Array.isArray(doc)) {
|
|
25
|
+
return callback(
|
|
26
|
+
MongoError.create({ message: 'doc parameter must be an object', driver: true })
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
insertDocuments(coll, [doc], options, (err, r) => {
|
|
31
|
+
if (callback == null) return;
|
|
32
|
+
if (err && callback) return callback(err);
|
|
33
|
+
// Workaround for pre 2.6 servers
|
|
34
|
+
if (r == null) return callback(null, { result: { ok: 1 } });
|
|
35
|
+
// Add values to top level to ensure crud spec compatibility
|
|
36
|
+
r.insertedCount = r.result.n;
|
|
37
|
+
r.insertedId = doc._id;
|
|
38
|
+
if (callback) callback(null, r);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function insertDocuments(coll, docs, options, callback) {
|
|
44
|
+
if (typeof options === 'function') (callback = options), (options = {});
|
|
45
|
+
options = options || {};
|
|
46
|
+
// Ensure we are operating on an array op docs
|
|
47
|
+
docs = Array.isArray(docs) ? docs : [docs];
|
|
48
|
+
|
|
49
|
+
// Final options for retryable writes and write concern
|
|
50
|
+
let finalOptions = Object.assign({}, options);
|
|
51
|
+
finalOptions = applyRetryableWrites(finalOptions, coll.s.db);
|
|
52
|
+
finalOptions = applyWriteConcern(finalOptions, { db: coll.s.db, collection: coll }, options);
|
|
53
|
+
|
|
54
|
+
// If keep going set unordered
|
|
55
|
+
if (finalOptions.keepGoing === true) finalOptions.ordered = false;
|
|
56
|
+
finalOptions.serializeFunctions = options.serializeFunctions || coll.s.serializeFunctions;
|
|
57
|
+
|
|
58
|
+
docs = prepareDocs(coll, docs, options);
|
|
59
|
+
|
|
60
|
+
// File inserts
|
|
61
|
+
coll.s.topology.insert(coll.s.namespace, docs, finalOptions, (err, result) => {
|
|
62
|
+
if (callback == null) return;
|
|
63
|
+
if (err) return handleCallback(callback, err);
|
|
64
|
+
if (result == null) return handleCallback(callback, null, null);
|
|
65
|
+
if (result.result.code) return handleCallback(callback, toError(result.result));
|
|
66
|
+
if (result.result.writeErrors)
|
|
67
|
+
return handleCallback(callback, toError(result.result.writeErrors[0]));
|
|
68
|
+
// Add docs to the list
|
|
69
|
+
result.ops = docs;
|
|
70
|
+
// Return the results
|
|
71
|
+
handleCallback(callback, null, result);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
module.exports = InsertOneOperation;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const OptionsOperation = require('./options_operation');
|
|
4
|
+
const handleCallback = require('../utils').handleCallback;
|
|
5
|
+
|
|
6
|
+
class IsCappedOperation extends OptionsOperation {
|
|
7
|
+
constructor(collection, options) {
|
|
8
|
+
super(collection, options);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
execute(callback) {
|
|
12
|
+
super.execute((err, document) => {
|
|
13
|
+
if (err) return handleCallback(callback, err);
|
|
14
|
+
handleCallback(callback, null, !!(document && document.capped));
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module.exports = IsCappedOperation;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const OperationBase = require('./operation').OperationBase;
|
|
4
|
+
const CommandCursor = require('../command_cursor');
|
|
5
|
+
const MongoError = require('../core').MongoError;
|
|
6
|
+
const resolveReadPreference = require('../utils').resolveReadPreference;
|
|
7
|
+
|
|
8
|
+
class ListIndexesOperation extends OperationBase {
|
|
9
|
+
constructor(collection, options) {
|
|
10
|
+
super(options);
|
|
11
|
+
|
|
12
|
+
this.collection = collection;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
execute() {
|
|
16
|
+
const coll = this.collection;
|
|
17
|
+
let options = this.options;
|
|
18
|
+
|
|
19
|
+
options = options || {};
|
|
20
|
+
// Clone the options
|
|
21
|
+
options = Object.assign({}, options);
|
|
22
|
+
// Determine the read preference in the options.
|
|
23
|
+
options.readPreference = resolveReadPreference(coll, options);
|
|
24
|
+
// Set the CommandCursor constructor
|
|
25
|
+
options.cursorFactory = CommandCursor;
|
|
26
|
+
// Set the promiseLibrary
|
|
27
|
+
options.promiseLibrary = coll.s.promiseLibrary;
|
|
28
|
+
|
|
29
|
+
if (!coll.s.topology.capabilities()) {
|
|
30
|
+
throw new MongoError('cannot connect to server');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Cursor options
|
|
34
|
+
let cursor = options.batchSize ? { batchSize: options.batchSize } : {};
|
|
35
|
+
|
|
36
|
+
// We have a list collections command
|
|
37
|
+
if (coll.s.topology.capabilities().hasListIndexesCommand) {
|
|
38
|
+
// Build the command
|
|
39
|
+
const command = { listIndexes: coll.collectionName, cursor: cursor };
|
|
40
|
+
// Execute the cursor
|
|
41
|
+
cursor = coll.s.topology.cursor(
|
|
42
|
+
coll.s.namespace.withCollection('$cmd').toString(),
|
|
43
|
+
command,
|
|
44
|
+
options
|
|
45
|
+
);
|
|
46
|
+
// Do we have a readPreference, apply it
|
|
47
|
+
if (options.readPreference) cursor.setReadPreference(options.readPreference);
|
|
48
|
+
// Return the cursor
|
|
49
|
+
return cursor;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Get the namespace
|
|
53
|
+
const namespace = coll.s.namespace.withCollection('system.indexes');
|
|
54
|
+
const ns = namespace.toString();
|
|
55
|
+
// Get the query
|
|
56
|
+
cursor = coll.s.topology.cursor(ns, { find: ns, query: { ns: coll.namespace } }, options);
|
|
57
|
+
// Do we have a readPreference, apply it
|
|
58
|
+
if (options.readPreference) cursor.setReadPreference(options.readPreference);
|
|
59
|
+
// Set the passed in batch size if one was provided
|
|
60
|
+
if (options.batchSize) cursor = cursor.batchSize(options.batchSize);
|
|
61
|
+
// Return the cursor
|
|
62
|
+
return cursor;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
module.exports = ListIndexesOperation;
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const applyWriteConcern = require('../utils').applyWriteConcern;
|
|
4
|
+
const Code = require('../core').BSON.Code;
|
|
5
|
+
const decorateWithCollation = require('../utils').decorateWithCollation;
|
|
6
|
+
const decorateWithReadConcern = require('../utils').decorateWithReadConcern;
|
|
7
|
+
const executeCommand = require('./db_ops').executeCommand;
|
|
8
|
+
const handleCallback = require('../utils').handleCallback;
|
|
9
|
+
const isObject = require('../utils').isObject;
|
|
10
|
+
const loadDb = require('../dynamic_loaders').loadDb;
|
|
11
|
+
const OperationBase = require('./operation').OperationBase;
|
|
12
|
+
const resolveReadPreference = require('../utils').resolveReadPreference;
|
|
13
|
+
const toError = require('../utils').toError;
|
|
14
|
+
|
|
15
|
+
const exclusionList = [
|
|
16
|
+
'readPreference',
|
|
17
|
+
'session',
|
|
18
|
+
'bypassDocumentValidation',
|
|
19
|
+
'w',
|
|
20
|
+
'wtimeout',
|
|
21
|
+
'j',
|
|
22
|
+
'writeConcern'
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Run Map Reduce across a collection. Be aware that the inline option for out will return an array of results not a collection.
|
|
27
|
+
*
|
|
28
|
+
* @class
|
|
29
|
+
* @property {Collection} a Collection instance.
|
|
30
|
+
* @property {(function|string)} map The mapping function.
|
|
31
|
+
* @property {(function|string)} reduce The reduce function.
|
|
32
|
+
* @property {object} [options] Optional settings. See Collection.prototype.mapReduce for a list of options.
|
|
33
|
+
*/
|
|
34
|
+
class MapReduceOperation extends OperationBase {
|
|
35
|
+
/**
|
|
36
|
+
* Constructs a MapReduce operation.
|
|
37
|
+
*
|
|
38
|
+
* @param {Collection} a Collection instance.
|
|
39
|
+
* @param {(function|string)} map The mapping function.
|
|
40
|
+
* @param {(function|string)} reduce The reduce function.
|
|
41
|
+
* @param {object} [options] Optional settings. See Collection.prototype.mapReduce for a list of options.
|
|
42
|
+
*/
|
|
43
|
+
constructor(collection, map, reduce, options) {
|
|
44
|
+
super(options);
|
|
45
|
+
|
|
46
|
+
this.collection = collection;
|
|
47
|
+
this.map = map;
|
|
48
|
+
this.reduce = reduce;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Execute the operation.
|
|
53
|
+
*
|
|
54
|
+
* @param {Collection~resultCallback} [callback] The command result callback
|
|
55
|
+
*/
|
|
56
|
+
execute(callback) {
|
|
57
|
+
const coll = this.collection;
|
|
58
|
+
const map = this.map;
|
|
59
|
+
const reduce = this.reduce;
|
|
60
|
+
let options = this.options;
|
|
61
|
+
|
|
62
|
+
const mapCommandHash = {
|
|
63
|
+
mapreduce: coll.collectionName,
|
|
64
|
+
map: map,
|
|
65
|
+
reduce: reduce
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// Add any other options passed in
|
|
69
|
+
for (let n in options) {
|
|
70
|
+
if ('scope' === n) {
|
|
71
|
+
mapCommandHash[n] = processScope(options[n]);
|
|
72
|
+
} else {
|
|
73
|
+
// Only include if not in exclusion list
|
|
74
|
+
if (exclusionList.indexOf(n) === -1) {
|
|
75
|
+
mapCommandHash[n] = options[n];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
options = Object.assign({}, options);
|
|
81
|
+
|
|
82
|
+
// Ensure we have the right read preference inheritance
|
|
83
|
+
options.readPreference = resolveReadPreference(coll, options);
|
|
84
|
+
|
|
85
|
+
// If we have a read preference and inline is not set as output fail hard
|
|
86
|
+
if (
|
|
87
|
+
options.readPreference !== false &&
|
|
88
|
+
options.readPreference !== 'primary' &&
|
|
89
|
+
options['out'] &&
|
|
90
|
+
(options['out'].inline !== 1 && options['out'] !== 'inline')
|
|
91
|
+
) {
|
|
92
|
+
// Force readPreference to primary
|
|
93
|
+
options.readPreference = 'primary';
|
|
94
|
+
// Decorate command with writeConcern if supported
|
|
95
|
+
applyWriteConcern(mapCommandHash, { db: coll.s.db, collection: coll }, options);
|
|
96
|
+
} else {
|
|
97
|
+
decorateWithReadConcern(mapCommandHash, coll, options);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Is bypassDocumentValidation specified
|
|
101
|
+
if (options.bypassDocumentValidation === true) {
|
|
102
|
+
mapCommandHash.bypassDocumentValidation = options.bypassDocumentValidation;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Have we specified collation
|
|
106
|
+
try {
|
|
107
|
+
decorateWithCollation(mapCommandHash, coll, options);
|
|
108
|
+
} catch (err) {
|
|
109
|
+
return callback(err, null);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Execute command
|
|
113
|
+
executeCommand(coll.s.db, mapCommandHash, options, (err, result) => {
|
|
114
|
+
if (err) return handleCallback(callback, err);
|
|
115
|
+
// Check if we have an error
|
|
116
|
+
if (1 !== result.ok || result.err || result.errmsg) {
|
|
117
|
+
return handleCallback(callback, toError(result));
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Create statistics value
|
|
121
|
+
const stats = {};
|
|
122
|
+
if (result.timeMillis) stats['processtime'] = result.timeMillis;
|
|
123
|
+
if (result.counts) stats['counts'] = result.counts;
|
|
124
|
+
if (result.timing) stats['timing'] = result.timing;
|
|
125
|
+
|
|
126
|
+
// invoked with inline?
|
|
127
|
+
if (result.results) {
|
|
128
|
+
// If we wish for no verbosity
|
|
129
|
+
if (options['verbose'] == null || !options['verbose']) {
|
|
130
|
+
return handleCallback(callback, null, result.results);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return handleCallback(callback, null, { results: result.results, stats: stats });
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// The returned collection
|
|
137
|
+
let collection = null;
|
|
138
|
+
|
|
139
|
+
// If we have an object it's a different db
|
|
140
|
+
if (result.result != null && typeof result.result === 'object') {
|
|
141
|
+
const doc = result.result;
|
|
142
|
+
// Return a collection from another db
|
|
143
|
+
let Db = loadDb();
|
|
144
|
+
collection = new Db(doc.db, coll.s.db.s.topology, coll.s.db.s.options).collection(
|
|
145
|
+
doc.collection
|
|
146
|
+
);
|
|
147
|
+
} else {
|
|
148
|
+
// Create a collection object that wraps the result collection
|
|
149
|
+
collection = coll.s.db.collection(result.result);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// If we wish for no verbosity
|
|
153
|
+
if (options['verbose'] == null || !options['verbose']) {
|
|
154
|
+
return handleCallback(callback, err, collection);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Return stats as third set of values
|
|
158
|
+
handleCallback(callback, err, { collection: collection, stats: stats });
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Functions that are passed as scope args must
|
|
165
|
+
* be converted to Code instances.
|
|
166
|
+
* @ignore
|
|
167
|
+
*/
|
|
168
|
+
function processScope(scope) {
|
|
169
|
+
if (!isObject(scope) || scope._bsontype === 'ObjectID') {
|
|
170
|
+
return scope;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const keys = Object.keys(scope);
|
|
174
|
+
let key;
|
|
175
|
+
const new_scope = {};
|
|
176
|
+
|
|
177
|
+
for (let i = keys.length - 1; i >= 0; i--) {
|
|
178
|
+
key = keys[i];
|
|
179
|
+
if ('function' === typeof scope[key]) {
|
|
180
|
+
new_scope[key] = new Code(String(scope[key]));
|
|
181
|
+
} else {
|
|
182
|
+
new_scope[key] = processScope(scope[key]);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return new_scope;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
module.exports = MapReduceOperation;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const Aspect = require('./operation').Aspect;
|
|
4
|
+
const defineAspects = require('./operation').defineAspects;
|
|
5
|
+
const OperationBase = require('./operation').OperationBase;
|
|
6
|
+
const nextObject = require('./common_functions').nextObject;
|
|
7
|
+
|
|
8
|
+
class NextOperation extends OperationBase {
|
|
9
|
+
constructor(cursor) {
|
|
10
|
+
super();
|
|
11
|
+
|
|
12
|
+
this.cursor = cursor;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
execute(callback) {
|
|
16
|
+
const cursor = this.cursor;
|
|
17
|
+
|
|
18
|
+
// Return the currentDoc if someone called hasNext first
|
|
19
|
+
if (cursor.s.currentDoc) {
|
|
20
|
+
const doc = cursor.s.currentDoc;
|
|
21
|
+
cursor.s.currentDoc = null;
|
|
22
|
+
return callback(null, doc);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Return the next object
|
|
26
|
+
nextObject(cursor, callback);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
defineAspects(NextOperation, Aspect.SKIP_SESSION);
|
|
31
|
+
|
|
32
|
+
module.exports = NextOperation;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const Aspect = {
|
|
4
|
+
READ_OPERATION: Symbol('READ_OPERATION'),
|
|
5
|
+
SKIP_SESSION: Symbol('SKIP_SESSION'),
|
|
6
|
+
WRITE_OPERATION: Symbol('WRITE_OPERATION'),
|
|
7
|
+
RETRYABLE: Symbol('RETRYABLE'),
|
|
8
|
+
EXECUTE_WITH_SELECTION: Symbol('EXECUTE_WITH_SELECTION')
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* This class acts as a parent class for any operation and is responsible for setting this.options,
|
|
13
|
+
* as well as setting and getting a session.
|
|
14
|
+
* Additionally, this class implements `hasAspect`, which determines whether an operation has
|
|
15
|
+
* a specific aspect, including `SKIP_SESSION` and other aspects to encode retryability
|
|
16
|
+
* and other functionality.
|
|
17
|
+
*/
|
|
18
|
+
class OperationBase {
|
|
19
|
+
constructor(options) {
|
|
20
|
+
this.options = Object.assign({}, options);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
hasAspect(aspect) {
|
|
24
|
+
if (this.constructor.aspects == null) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
return this.constructor.aspects.has(aspect);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
set session(session) {
|
|
31
|
+
Object.assign(this.options, { session });
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
get session() {
|
|
35
|
+
return this.options.session;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
clearSession() {
|
|
39
|
+
delete this.options.session;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
execute() {
|
|
43
|
+
throw new TypeError('`execute` must be implemented for OperationBase subclasses');
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function defineAspects(operation, aspects) {
|
|
48
|
+
if (!Array.isArray(aspects) && !(aspects instanceof Set)) {
|
|
49
|
+
aspects = [aspects];
|
|
50
|
+
}
|
|
51
|
+
aspects = new Set(aspects);
|
|
52
|
+
Object.defineProperty(operation, 'aspects', {
|
|
53
|
+
value: aspects,
|
|
54
|
+
writable: false
|
|
55
|
+
});
|
|
56
|
+
return aspects;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
module.exports = {
|
|
60
|
+
Aspect,
|
|
61
|
+
defineAspects,
|
|
62
|
+
OperationBase
|
|
63
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const OperationBase = require('./operation').OperationBase;
|
|
4
|
+
const handleCallback = require('../utils').handleCallback;
|
|
5
|
+
const MongoError = require('../core').MongoError;
|
|
6
|
+
|
|
7
|
+
class OptionsOperation extends OperationBase {
|
|
8
|
+
constructor(collection, options) {
|
|
9
|
+
super(options);
|
|
10
|
+
|
|
11
|
+
this.collection = collection;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
execute(callback) {
|
|
15
|
+
const coll = this.collection;
|
|
16
|
+
const opts = this.options;
|
|
17
|
+
|
|
18
|
+
coll.s.db.listCollections({ name: coll.collectionName }, opts).toArray((err, collections) => {
|
|
19
|
+
if (err) return handleCallback(callback, err);
|
|
20
|
+
if (collections.length === 0) {
|
|
21
|
+
return handleCallback(
|
|
22
|
+
callback,
|
|
23
|
+
MongoError.create({ message: `collection ${coll.namespace} not found`, driver: true })
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
handleCallback(callback, err, collections[0].options || null);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
module.exports = OptionsOperation;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const CommandOperation = require('./command');
|
|
4
|
+
|
|
5
|
+
class ProfilingLevelOperation extends CommandOperation {
|
|
6
|
+
constructor(db, command, options) {
|
|
7
|
+
super(db, options);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
_buildCommand() {
|
|
11
|
+
const command = { profile: -1 };
|
|
12
|
+
|
|
13
|
+
return command;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
execute(callback) {
|
|
17
|
+
super.execute((err, doc) => {
|
|
18
|
+
if (err == null && doc.ok === 1) {
|
|
19
|
+
const was = doc.was;
|
|
20
|
+
if (was === 0) return callback(null, 'off');
|
|
21
|
+
if (was === 1) return callback(null, 'slow_only');
|
|
22
|
+
if (was === 2) return callback(null, 'all');
|
|
23
|
+
return callback(new Error('Error: illegal profiling level value ' + was), null);
|
|
24
|
+
} else {
|
|
25
|
+
err != null ? callback(err, null) : callback(new Error('Error with profile command'), null);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
module.exports = ProfilingLevelOperation;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const CommandOperation = require('./command');
|
|
4
|
+
const handleCallback = require('../utils').handleCallback;
|
|
5
|
+
|
|
6
|
+
class ReIndexOperation extends CommandOperation {
|
|
7
|
+
constructor(collection, options) {
|
|
8
|
+
super(collection.s.db, options, collection);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
_buildCommand() {
|
|
12
|
+
const collection = this.collection;
|
|
13
|
+
|
|
14
|
+
const cmd = { reIndex: collection.collectionName };
|
|
15
|
+
|
|
16
|
+
return cmd;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
execute(callback) {
|
|
20
|
+
super.execute((err, result) => {
|
|
21
|
+
if (callback == null) return;
|
|
22
|
+
if (err) return handleCallback(callback, err, null);
|
|
23
|
+
handleCallback(callback, null, result.ok ? true : false);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
module.exports = ReIndexOperation;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const Aspect = require('./operation').Aspect;
|
|
4
|
+
const CommandOperation = require('./command');
|
|
5
|
+
const defineAspects = require('./operation').defineAspects;
|
|
6
|
+
const handleCallback = require('../utils').handleCallback;
|
|
7
|
+
const WriteConcern = require('../write_concern');
|
|
8
|
+
|
|
9
|
+
class RemoveUserOperation extends CommandOperation {
|
|
10
|
+
constructor(db, username, options) {
|
|
11
|
+
const commandOptions = {};
|
|
12
|
+
|
|
13
|
+
const writeConcern = WriteConcern.fromOptions(options);
|
|
14
|
+
if (writeConcern != null) {
|
|
15
|
+
commandOptions.writeConcern = writeConcern;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (options.dbName) {
|
|
19
|
+
commandOptions.dbName = options.dbName;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Add maxTimeMS to options if set
|
|
23
|
+
if (typeof options.maxTimeMS === 'number') {
|
|
24
|
+
commandOptions.maxTimeMS = options.maxTimeMS;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
super(db, commandOptions);
|
|
28
|
+
|
|
29
|
+
this.username = username;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
_buildCommand() {
|
|
33
|
+
const username = this.username;
|
|
34
|
+
|
|
35
|
+
// Build the command to execute
|
|
36
|
+
const command = { dropUser: username };
|
|
37
|
+
|
|
38
|
+
return command;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
execute(callback) {
|
|
42
|
+
// Attempt to execute command
|
|
43
|
+
super.execute((err, result) => {
|
|
44
|
+
if (err) return handleCallback(callback, err, null);
|
|
45
|
+
handleCallback(callback, err, result.ok ? true : false);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
defineAspects(RemoveUserOperation, [Aspect.WRITE_OPERATION, Aspect.SKIP_SESSIONS]);
|
|
51
|
+
|
|
52
|
+
module.exports = RemoveUserOperation;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const OperationBase = require('./operation').OperationBase;
|
|
4
|
+
const applyWriteConcern = require('../utils').applyWriteConcern;
|
|
5
|
+
const checkCollectionName = require('../utils').checkCollectionName;
|
|
6
|
+
const executeDbAdminCommand = require('./db_ops').executeDbAdminCommand;
|
|
7
|
+
const handleCallback = require('../utils').handleCallback;
|
|
8
|
+
const loadCollection = require('../dynamic_loaders').loadCollection;
|
|
9
|
+
const toError = require('../utils').toError;
|
|
10
|
+
|
|
11
|
+
class RenameOperation extends OperationBase {
|
|
12
|
+
constructor(collection, newName, options) {
|
|
13
|
+
super(options);
|
|
14
|
+
|
|
15
|
+
this.collection = collection;
|
|
16
|
+
this.newName = newName;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
execute(callback) {
|
|
20
|
+
const coll = this.collection;
|
|
21
|
+
const newName = this.newName;
|
|
22
|
+
const options = this.options;
|
|
23
|
+
|
|
24
|
+
let Collection = loadCollection();
|
|
25
|
+
// Check the collection name
|
|
26
|
+
checkCollectionName(newName);
|
|
27
|
+
// Build the command
|
|
28
|
+
const renameCollection = coll.namespace;
|
|
29
|
+
const toCollection = coll.s.namespace.withCollection(newName).toString();
|
|
30
|
+
const dropTarget = typeof options.dropTarget === 'boolean' ? options.dropTarget : false;
|
|
31
|
+
const cmd = { renameCollection: renameCollection, to: toCollection, dropTarget: dropTarget };
|
|
32
|
+
|
|
33
|
+
// Decorate command with writeConcern if supported
|
|
34
|
+
applyWriteConcern(cmd, { db: coll.s.db, collection: coll }, options);
|
|
35
|
+
|
|
36
|
+
// Execute against admin
|
|
37
|
+
executeDbAdminCommand(coll.s.db.admin().s.db, cmd, options, (err, doc) => {
|
|
38
|
+
if (err) return handleCallback(callback, err, null);
|
|
39
|
+
// We have an error
|
|
40
|
+
if (doc.errmsg) return handleCallback(callback, toError(doc), null);
|
|
41
|
+
try {
|
|
42
|
+
return handleCallback(
|
|
43
|
+
callback,
|
|
44
|
+
null,
|
|
45
|
+
new Collection(
|
|
46
|
+
coll.s.db,
|
|
47
|
+
coll.s.topology,
|
|
48
|
+
coll.databaseName,
|
|
49
|
+
newName,
|
|
50
|
+
coll.s.pkFactory,
|
|
51
|
+
coll.s.options
|
|
52
|
+
)
|
|
53
|
+
);
|
|
54
|
+
} catch (err) {
|
|
55
|
+
return handleCallback(callback, toError(err), null);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
module.exports = RenameOperation;
|