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,165 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const MongoError = require('../core').MongoError;
|
|
4
|
+
const Aspect = require('./operation').Aspect;
|
|
5
|
+
const OperationBase = require('./operation').OperationBase;
|
|
6
|
+
const ReadPreference = require('../core').ReadPreference;
|
|
7
|
+
const isRetryableError = require('../core/error').isRetryableError;
|
|
8
|
+
const maxWireVersion = require('../core/utils').maxWireVersion;
|
|
9
|
+
const isUnifiedTopology = require('../core/utils').isUnifiedTopology;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Executes the given operation with provided arguments.
|
|
13
|
+
*
|
|
14
|
+
* This method reduces large amounts of duplication in the entire codebase by providing
|
|
15
|
+
* a single point for determining whether callbacks or promises should be used. Additionally
|
|
16
|
+
* it allows for a single point of entry to provide features such as implicit sessions, which
|
|
17
|
+
* are required by the Driver Sessions specification in the event that a ClientSession is
|
|
18
|
+
* not provided
|
|
19
|
+
*
|
|
20
|
+
* @param {object} topology The topology to execute this operation on
|
|
21
|
+
* @param {Operation} operation The operation to execute
|
|
22
|
+
* @param {function} callback The command result callback
|
|
23
|
+
*/
|
|
24
|
+
function executeOperation(topology, operation, callback) {
|
|
25
|
+
if (topology == null) {
|
|
26
|
+
throw new TypeError('This method requires a valid topology instance');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (!(operation instanceof OperationBase)) {
|
|
30
|
+
throw new TypeError('This method requires a valid operation instance');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (
|
|
34
|
+
isUnifiedTopology(topology) &&
|
|
35
|
+
!operation.hasAspect(Aspect.SKIP_SESSION) &&
|
|
36
|
+
topology.shouldCheckForSessionSupport()
|
|
37
|
+
) {
|
|
38
|
+
// TODO: this is only supported for unified topology, the first part of this check
|
|
39
|
+
// should go away when we drop legacy topology types.
|
|
40
|
+
topology.selectServer(ReadPreference.primaryPreferred, err => {
|
|
41
|
+
if (err) {
|
|
42
|
+
callback(err);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
executeOperation(topology, operation, callback);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const Promise = topology.s.promiseLibrary;
|
|
53
|
+
|
|
54
|
+
// The driver sessions spec mandates that we implicitly create sessions for operations
|
|
55
|
+
// that are not explicitly provided with a session.
|
|
56
|
+
let session, owner;
|
|
57
|
+
if (!operation.hasAspect(Aspect.SKIP_SESSION) && topology.hasSessionSupport()) {
|
|
58
|
+
if (operation.session == null) {
|
|
59
|
+
owner = Symbol();
|
|
60
|
+
session = topology.startSession({ owner });
|
|
61
|
+
operation.session = session;
|
|
62
|
+
} else if (operation.session.hasEnded) {
|
|
63
|
+
throw new MongoError('Use of expired sessions is not permitted');
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const makeExecuteCallback = (resolve, reject) =>
|
|
68
|
+
function executeCallback(err, result) {
|
|
69
|
+
if (session && session.owner === owner) {
|
|
70
|
+
session.endSession(() => {
|
|
71
|
+
if (operation.session === session) {
|
|
72
|
+
operation.clearSession();
|
|
73
|
+
}
|
|
74
|
+
if (err) return reject(err);
|
|
75
|
+
resolve(result);
|
|
76
|
+
});
|
|
77
|
+
} else {
|
|
78
|
+
if (err) return reject(err);
|
|
79
|
+
resolve(result);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// Execute using callback
|
|
84
|
+
if (typeof callback === 'function') {
|
|
85
|
+
const handler = makeExecuteCallback(
|
|
86
|
+
result => callback(null, result),
|
|
87
|
+
err => callback(err, null)
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
if (operation.hasAspect(Aspect.EXECUTE_WITH_SELECTION)) {
|
|
92
|
+
return executeWithServerSelection(topology, operation, handler);
|
|
93
|
+
} else {
|
|
94
|
+
return operation.execute(handler);
|
|
95
|
+
}
|
|
96
|
+
} catch (e) {
|
|
97
|
+
handler(e);
|
|
98
|
+
throw e;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return new Promise(function(resolve, reject) {
|
|
103
|
+
const handler = makeExecuteCallback(resolve, reject);
|
|
104
|
+
|
|
105
|
+
try {
|
|
106
|
+
if (operation.hasAspect(Aspect.EXECUTE_WITH_SELECTION)) {
|
|
107
|
+
return executeWithServerSelection(topology, operation, handler);
|
|
108
|
+
} else {
|
|
109
|
+
return operation.execute(handler);
|
|
110
|
+
}
|
|
111
|
+
} catch (e) {
|
|
112
|
+
handler(e);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function supportsRetryableReads(server) {
|
|
118
|
+
return maxWireVersion(server) >= 6;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function executeWithServerSelection(topology, operation, callback) {
|
|
122
|
+
const readPreference = operation.readPreference || ReadPreference.primary;
|
|
123
|
+
|
|
124
|
+
function callbackWithRetry(err, result) {
|
|
125
|
+
if (err == null) {
|
|
126
|
+
return callback(null, result);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (!isRetryableError(err)) {
|
|
130
|
+
return callback(err);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// select a new server, and attempt to retry the operation
|
|
134
|
+
topology.selectServer(readPreference, (err, server) => {
|
|
135
|
+
if (err || !supportsRetryableReads(server)) {
|
|
136
|
+
callback(err, null);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
operation.execute(server, callback);
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// select a server, and execute the operation against it
|
|
145
|
+
topology.selectServer(readPreference, (err, server) => {
|
|
146
|
+
if (err) {
|
|
147
|
+
callback(err, null);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const shouldRetryReads =
|
|
152
|
+
topology.s.options.retryReads !== false &&
|
|
153
|
+
(operation.session && !operation.session.inTransaction()) &&
|
|
154
|
+
supportsRetryableReads(server);
|
|
155
|
+
|
|
156
|
+
if (operation.hasAspect(Aspect.RETRYABLE) && shouldRetryReads) {
|
|
157
|
+
operation.execute(server, callbackWithRetry);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
operation.execute(server, callback);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
module.exports = executeOperation;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const Aspect = require('./operation').Aspect;
|
|
4
|
+
const CoreCursor = require('../core').Cursor;
|
|
5
|
+
const defineAspects = require('./operation').defineAspects;
|
|
6
|
+
const OperationBase = require('./operation').OperationBase;
|
|
7
|
+
|
|
8
|
+
class ExplainOperation extends OperationBase {
|
|
9
|
+
constructor(cursor) {
|
|
10
|
+
super();
|
|
11
|
+
|
|
12
|
+
this.cursor = cursor;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
execute() {
|
|
16
|
+
const cursor = this.cursor;
|
|
17
|
+
return CoreCursor.prototype.next.apply(cursor, arguments);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
defineAspects(ExplainOperation, Aspect.SKIP_SESSION);
|
|
22
|
+
|
|
23
|
+
module.exports = ExplainOperation;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const OperationBase = require('./operation').OperationBase;
|
|
4
|
+
const applyRetryableWrites = require('../utils').applyRetryableWrites;
|
|
5
|
+
const applyWriteConcern = require('../utils').applyWriteConcern;
|
|
6
|
+
const decorateWithCollation = require('../utils').decorateWithCollation;
|
|
7
|
+
const executeCommand = require('./db_ops').executeCommand;
|
|
8
|
+
const formattedOrderClause = require('../utils').formattedOrderClause;
|
|
9
|
+
const handleCallback = require('../utils').handleCallback;
|
|
10
|
+
const ReadPreference = require('../core').ReadPreference;
|
|
11
|
+
|
|
12
|
+
class FindAndModifyOperation extends OperationBase {
|
|
13
|
+
constructor(collection, query, sort, doc, options) {
|
|
14
|
+
super(options);
|
|
15
|
+
|
|
16
|
+
this.collection = collection;
|
|
17
|
+
this.query = query;
|
|
18
|
+
this.sort = sort;
|
|
19
|
+
this.doc = doc;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
execute(callback) {
|
|
23
|
+
const coll = this.collection;
|
|
24
|
+
const query = this.query;
|
|
25
|
+
const sort = formattedOrderClause(this.sort);
|
|
26
|
+
const doc = this.doc;
|
|
27
|
+
let options = this.options;
|
|
28
|
+
|
|
29
|
+
// Create findAndModify command object
|
|
30
|
+
const queryObject = {
|
|
31
|
+
findAndModify: coll.collectionName,
|
|
32
|
+
query: query
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
if (sort) {
|
|
36
|
+
queryObject.sort = sort;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
queryObject.new = options.new ? true : false;
|
|
40
|
+
queryObject.remove = options.remove ? true : false;
|
|
41
|
+
queryObject.upsert = options.upsert ? true : false;
|
|
42
|
+
|
|
43
|
+
const projection = options.projection || options.fields;
|
|
44
|
+
|
|
45
|
+
if (projection) {
|
|
46
|
+
queryObject.fields = projection;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (options.arrayFilters) {
|
|
50
|
+
queryObject.arrayFilters = options.arrayFilters;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (doc && !options.remove) {
|
|
54
|
+
queryObject.update = doc;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (options.maxTimeMS) queryObject.maxTimeMS = options.maxTimeMS;
|
|
58
|
+
|
|
59
|
+
// Either use override on the function, or go back to default on either the collection
|
|
60
|
+
// level or db
|
|
61
|
+
options.serializeFunctions = options.serializeFunctions || coll.s.serializeFunctions;
|
|
62
|
+
|
|
63
|
+
// No check on the documents
|
|
64
|
+
options.checkKeys = false;
|
|
65
|
+
|
|
66
|
+
// Final options for retryable writes and write concern
|
|
67
|
+
options = applyRetryableWrites(options, coll.s.db);
|
|
68
|
+
options = applyWriteConcern(options, { db: coll.s.db, collection: coll }, options);
|
|
69
|
+
|
|
70
|
+
// Decorate the findAndModify command with the write Concern
|
|
71
|
+
if (options.writeConcern) {
|
|
72
|
+
queryObject.writeConcern = options.writeConcern;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Have we specified bypassDocumentValidation
|
|
76
|
+
if (options.bypassDocumentValidation === true) {
|
|
77
|
+
queryObject.bypassDocumentValidation = options.bypassDocumentValidation;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
options.readPreference = ReadPreference.primary;
|
|
81
|
+
|
|
82
|
+
// Have we specified collation
|
|
83
|
+
try {
|
|
84
|
+
decorateWithCollation(queryObject, coll, options);
|
|
85
|
+
} catch (err) {
|
|
86
|
+
return callback(err, null);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Execute the command
|
|
90
|
+
executeCommand(coll.s.db, queryObject, options, (err, result) => {
|
|
91
|
+
if (err) return handleCallback(callback, err, null);
|
|
92
|
+
|
|
93
|
+
return handleCallback(callback, null, result);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
module.exports = FindAndModifyOperation;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const handleCallback = require('../utils').handleCallback;
|
|
4
|
+
const OperationBase = require('./operation').OperationBase;
|
|
5
|
+
const toError = require('../utils').toError;
|
|
6
|
+
|
|
7
|
+
class FindOneOperation extends OperationBase {
|
|
8
|
+
constructor(collection, query, options) {
|
|
9
|
+
super(options);
|
|
10
|
+
|
|
11
|
+
this.collection = collection;
|
|
12
|
+
this.query = query;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
execute(callback) {
|
|
16
|
+
const coll = this.collection;
|
|
17
|
+
const query = this.query;
|
|
18
|
+
const options = this.options;
|
|
19
|
+
|
|
20
|
+
const cursor = coll
|
|
21
|
+
.find(query, options)
|
|
22
|
+
.limit(-1)
|
|
23
|
+
.batchSize(1);
|
|
24
|
+
|
|
25
|
+
// Return the item
|
|
26
|
+
cursor.next((err, item) => {
|
|
27
|
+
if (err != null) return handleCallback(callback, toError(err), null);
|
|
28
|
+
handleCallback(callback, null, item);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
module.exports = FindOneOperation;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const FindAndModifyOperation = require('./find_and_modify');
|
|
4
|
+
|
|
5
|
+
class FindOneAndDeleteOperation extends FindAndModifyOperation {
|
|
6
|
+
constructor(collection, filter, options) {
|
|
7
|
+
// Final options
|
|
8
|
+
const finalOptions = Object.assign({}, options);
|
|
9
|
+
finalOptions.fields = options.projection;
|
|
10
|
+
finalOptions.remove = true;
|
|
11
|
+
|
|
12
|
+
super(collection, filter, finalOptions.sort, null, finalOptions);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
module.exports = FindOneAndDeleteOperation;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const FindAndModifyOperation = require('./find_and_modify');
|
|
4
|
+
|
|
5
|
+
class FindOneAndReplaceOperation extends FindAndModifyOperation {
|
|
6
|
+
constructor(collection, filter, replacement, options) {
|
|
7
|
+
// Final options
|
|
8
|
+
const finalOptions = Object.assign({}, options);
|
|
9
|
+
finalOptions.fields = options.projection;
|
|
10
|
+
finalOptions.update = true;
|
|
11
|
+
finalOptions.new = options.returnOriginal !== void 0 ? !options.returnOriginal : false;
|
|
12
|
+
finalOptions.upsert = options.upsert !== void 0 ? !!options.upsert : false;
|
|
13
|
+
|
|
14
|
+
super(collection, filter, finalOptions.sort, replacement, finalOptions);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
module.exports = FindOneAndReplaceOperation;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const FindAndModifyOperation = require('./find_and_modify');
|
|
4
|
+
|
|
5
|
+
class FindOneAndUpdateOperation extends FindAndModifyOperation {
|
|
6
|
+
constructor(collection, filter, update, options) {
|
|
7
|
+
// Final options
|
|
8
|
+
const finalOptions = Object.assign({}, options);
|
|
9
|
+
finalOptions.fields = options.projection;
|
|
10
|
+
finalOptions.update = true;
|
|
11
|
+
finalOptions.new =
|
|
12
|
+
typeof options.returnOriginal === 'boolean' ? !options.returnOriginal : false;
|
|
13
|
+
finalOptions.upsert = typeof options.upsert === 'boolean' ? options.upsert : false;
|
|
14
|
+
|
|
15
|
+
super(collection, filter, finalOptions.sort, update, finalOptions);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module.exports = FindOneAndUpdateOperation;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const Aspect = require('./operation').Aspect;
|
|
4
|
+
const defineAspects = require('./operation').defineAspects;
|
|
5
|
+
const OperationBase = require('./operation').OperationBase;
|
|
6
|
+
const decorateCommand = require('../utils').decorateCommand;
|
|
7
|
+
const decorateWithReadConcern = require('../utils').decorateWithReadConcern;
|
|
8
|
+
const executeCommand = require('./db_ops').executeCommand;
|
|
9
|
+
const handleCallback = require('../utils').handleCallback;
|
|
10
|
+
const resolveReadPreference = require('../utils').resolveReadPreference;
|
|
11
|
+
const toError = require('../utils').toError;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Execute a geo search using a geo haystack index on a collection.
|
|
15
|
+
*
|
|
16
|
+
* @class
|
|
17
|
+
* @property {Collection} a Collection instance.
|
|
18
|
+
* @property {number} x Point to search on the x axis, ensure the indexes are ordered in the same order.
|
|
19
|
+
* @property {number} y Point to search on the y axis, ensure the indexes are ordered in the same order.
|
|
20
|
+
* @property {object} [options] Optional settings. See Collection.prototype.geoHaystackSearch for a list of options.
|
|
21
|
+
*/
|
|
22
|
+
class GeoHaystackSearchOperation extends OperationBase {
|
|
23
|
+
/**
|
|
24
|
+
* Construct a GeoHaystackSearch operation.
|
|
25
|
+
*
|
|
26
|
+
* @param {Collection} a Collection instance.
|
|
27
|
+
* @param {number} x Point to search on the x axis, ensure the indexes are ordered in the same order.
|
|
28
|
+
* @param {number} y Point to search on the y axis, ensure the indexes are ordered in the same order.
|
|
29
|
+
* @param {object} [options] Optional settings. See Collection.prototype.geoHaystackSearch for a list of options.
|
|
30
|
+
*/
|
|
31
|
+
constructor(collection, x, y, options) {
|
|
32
|
+
super(options);
|
|
33
|
+
|
|
34
|
+
this.collection = collection;
|
|
35
|
+
this.x = x;
|
|
36
|
+
this.y = y;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Execute the operation.
|
|
41
|
+
*
|
|
42
|
+
* @param {Collection~resultCallback} [callback] The command result callback
|
|
43
|
+
*/
|
|
44
|
+
execute(callback) {
|
|
45
|
+
const coll = this.collection;
|
|
46
|
+
const x = this.x;
|
|
47
|
+
const y = this.y;
|
|
48
|
+
let options = this.options;
|
|
49
|
+
|
|
50
|
+
// Build command object
|
|
51
|
+
let commandObject = {
|
|
52
|
+
geoSearch: coll.collectionName,
|
|
53
|
+
near: [x, y]
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// Remove read preference from hash if it exists
|
|
57
|
+
commandObject = decorateCommand(commandObject, options, ['readPreference', 'session']);
|
|
58
|
+
|
|
59
|
+
options = Object.assign({}, options);
|
|
60
|
+
// Ensure we have the right read preference inheritance
|
|
61
|
+
options.readPreference = resolveReadPreference(coll, options);
|
|
62
|
+
|
|
63
|
+
// Do we have a readConcern specified
|
|
64
|
+
decorateWithReadConcern(commandObject, coll, options);
|
|
65
|
+
|
|
66
|
+
// Execute the command
|
|
67
|
+
executeCommand(coll.s.db, commandObject, options, (err, res) => {
|
|
68
|
+
if (err) return handleCallback(callback, err);
|
|
69
|
+
if (res.err || res.errmsg) handleCallback(callback, toError(res));
|
|
70
|
+
// should we only be returning res.results here? Not sure if the user
|
|
71
|
+
// should see the other return information
|
|
72
|
+
handleCallback(callback, null, res);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
defineAspects(GeoHaystackSearchOperation, Aspect.READ_OPERATION);
|
|
78
|
+
|
|
79
|
+
module.exports = GeoHaystackSearchOperation;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const Aspect = require('./operation').Aspect;
|
|
4
|
+
const defineAspects = require('./operation').defineAspects;
|
|
5
|
+
const loadCursor = require('../dynamic_loaders').loadCursor;
|
|
6
|
+
const OperationBase = require('./operation').OperationBase;
|
|
7
|
+
const nextObject = require('./common_functions').nextObject;
|
|
8
|
+
|
|
9
|
+
class HasNextOperation extends OperationBase {
|
|
10
|
+
constructor(cursor) {
|
|
11
|
+
super();
|
|
12
|
+
|
|
13
|
+
this.cursor = cursor;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
execute(callback) {
|
|
17
|
+
const cursor = this.cursor;
|
|
18
|
+
let Cursor = loadCursor();
|
|
19
|
+
|
|
20
|
+
if (cursor.s.currentDoc) {
|
|
21
|
+
return callback(null, true);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (cursor.isNotified()) {
|
|
25
|
+
return callback(null, false);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
nextObject(cursor, (err, doc) => {
|
|
29
|
+
if (err) return callback(err, null);
|
|
30
|
+
if (cursor.s.state === Cursor.CLOSED || cursor.isDead()) return callback(null, false);
|
|
31
|
+
if (!doc) return callback(null, false);
|
|
32
|
+
cursor.s.currentDoc = doc;
|
|
33
|
+
callback(null, true);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
defineAspects(HasNextOperation, Aspect.SKIP_SESSION);
|
|
39
|
+
|
|
40
|
+
module.exports = HasNextOperation;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const OperationBase = require('./operation').OperationBase;
|
|
4
|
+
const handleCallback = require('../utils').handleCallback;
|
|
5
|
+
const indexInformationDb = require('./db_ops').indexInformation;
|
|
6
|
+
|
|
7
|
+
class IndexExistsOperation extends OperationBase {
|
|
8
|
+
constructor(collection, indexes, options) {
|
|
9
|
+
super(options);
|
|
10
|
+
|
|
11
|
+
this.collection = collection;
|
|
12
|
+
this.indexes = indexes;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
execute(callback) {
|
|
16
|
+
const coll = this.collection;
|
|
17
|
+
const indexes = this.indexes;
|
|
18
|
+
const options = this.options;
|
|
19
|
+
|
|
20
|
+
indexInformationDb(coll.s.db, coll.collectionName, options, (err, indexInformation) => {
|
|
21
|
+
// If we have an error return
|
|
22
|
+
if (err != null) return handleCallback(callback, err, null);
|
|
23
|
+
// Let's check for the index names
|
|
24
|
+
if (!Array.isArray(indexes))
|
|
25
|
+
return handleCallback(callback, null, indexInformation[indexes] != null);
|
|
26
|
+
// Check in list of indexes
|
|
27
|
+
for (let i = 0; i < indexes.length; i++) {
|
|
28
|
+
if (indexInformation[indexes[i]] == null) {
|
|
29
|
+
return handleCallback(callback, null, false);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// All keys found return true
|
|
34
|
+
return handleCallback(callback, null, true);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
module.exports = IndexExistsOperation;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const OperationBase = require('./operation').OperationBase;
|
|
4
|
+
const indexInformation = require('./common_functions').indexInformation;
|
|
5
|
+
|
|
6
|
+
class IndexInformationOperation extends OperationBase {
|
|
7
|
+
constructor(db, name, options) {
|
|
8
|
+
super(options);
|
|
9
|
+
|
|
10
|
+
this.db = db;
|
|
11
|
+
this.name = name;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
execute(callback) {
|
|
15
|
+
const db = this.db;
|
|
16
|
+
const name = this.name;
|
|
17
|
+
const options = this.options;
|
|
18
|
+
|
|
19
|
+
indexInformation(db, name, options, callback);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
module.exports = IndexInformationOperation;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const OperationBase = require('./operation').OperationBase;
|
|
4
|
+
const indexInformation = require('./common_functions').indexInformation;
|
|
5
|
+
|
|
6
|
+
class IndexesOperation extends OperationBase {
|
|
7
|
+
constructor(collection, options) {
|
|
8
|
+
super(options);
|
|
9
|
+
|
|
10
|
+
this.collection = collection;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
execute(callback) {
|
|
14
|
+
const coll = this.collection;
|
|
15
|
+
let options = this.options;
|
|
16
|
+
|
|
17
|
+
options = Object.assign({}, { full: true }, options);
|
|
18
|
+
indexInformation(coll.s.db, coll.collectionName, options, callback);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
module.exports = IndexesOperation;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const OperationBase = require('./operation').OperationBase;
|
|
4
|
+
const BulkWriteOperation = require('./bulk_write');
|
|
5
|
+
const MongoError = require('../core').MongoError;
|
|
6
|
+
const prepareDocs = require('./common_functions').prepareDocs;
|
|
7
|
+
|
|
8
|
+
class InsertManyOperation extends OperationBase {
|
|
9
|
+
constructor(collection, docs, options) {
|
|
10
|
+
super(options);
|
|
11
|
+
|
|
12
|
+
this.collection = collection;
|
|
13
|
+
this.docs = docs;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
execute(callback) {
|
|
17
|
+
const coll = this.collection;
|
|
18
|
+
let docs = this.docs;
|
|
19
|
+
const options = this.options;
|
|
20
|
+
|
|
21
|
+
if (!Array.isArray(docs)) {
|
|
22
|
+
return callback(
|
|
23
|
+
MongoError.create({ message: 'docs parameter must be an array of documents', driver: true })
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// If keep going set unordered
|
|
28
|
+
options['serializeFunctions'] = options['serializeFunctions'] || coll.s.serializeFunctions;
|
|
29
|
+
|
|
30
|
+
docs = prepareDocs(coll, docs, options);
|
|
31
|
+
|
|
32
|
+
// Generate the bulk write operations
|
|
33
|
+
const operations = [
|
|
34
|
+
{
|
|
35
|
+
insertMany: docs
|
|
36
|
+
}
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
const bulkWriteOperation = new BulkWriteOperation(coll, operations, options);
|
|
40
|
+
|
|
41
|
+
bulkWriteOperation.execute((err, result) => {
|
|
42
|
+
if (err) return callback(err, null);
|
|
43
|
+
callback(null, mapInsertManyResults(docs, result));
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function mapInsertManyResults(docs, r) {
|
|
49
|
+
const finalResult = {
|
|
50
|
+
result: { ok: 1, n: r.insertedCount },
|
|
51
|
+
ops: docs,
|
|
52
|
+
insertedCount: r.insertedCount,
|
|
53
|
+
insertedIds: r.insertedIds
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
if (r.getLastOp()) {
|
|
57
|
+
finalResult.result.opTime = r.getLastOp();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return finalResult;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
module.exports = InsertManyOperation;
|