diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/scripting/mozjs/cursor.cpp | 14 | ||||
-rw-r--r-- | src/mongo/scripting/mozjs/cursor.h | 3 | ||||
-rw-r--r-- | src/mongo/shell/collection.js | 19 | ||||
-rw-r--r-- | src/mongo/shell/db.js | 5 | ||||
-rw-r--r-- | src/mongo/shell/query.js | 37 |
5 files changed, 73 insertions, 5 deletions
diff --git a/src/mongo/scripting/mozjs/cursor.cpp b/src/mongo/scripting/mozjs/cursor.cpp index fb1d48e8c83..0b107a31367 100644 --- a/src/mongo/scripting/mozjs/cursor.cpp +++ b/src/mongo/scripting/mozjs/cursor.cpp @@ -40,12 +40,13 @@ namespace mongo { namespace mozjs { -const JSFunctionSpec CursorInfo::methods[6] = { +const JSFunctionSpec CursorInfo::methods[7] = { MONGO_ATTACH_JS_CONSTRAINED_METHOD_NO_PROTO(close, CursorInfo), MONGO_ATTACH_JS_CONSTRAINED_METHOD_NO_PROTO(hasNext, CursorInfo), MONGO_ATTACH_JS_CONSTRAINED_METHOD_NO_PROTO(next, CursorInfo), MONGO_ATTACH_JS_CONSTRAINED_METHOD_NO_PROTO(objsLeftInBatch, CursorInfo), MONGO_ATTACH_JS_CONSTRAINED_METHOD_NO_PROTO(readOnly, CursorInfo), + MONGO_ATTACH_JS_CONSTRAINED_METHOD_NO_PROTO(isClosed, CursorInfo), JS_FS_END, }; @@ -126,5 +127,16 @@ void CursorInfo::Functions::close::call(JSContext* cx, JS::CallArgs args) { args.rval().setUndefined(); } +void CursorInfo::Functions::isClosed::call(JSContext* cx, JS::CallArgs args) { + auto cursor = getCursor(args); + + if (!cursor) { + args.rval().setBoolean(true); + return; + } + + args.rval().setBoolean(cursor->isDead()); +} + } // namespace mozjs } // namespace mongo diff --git a/src/mongo/scripting/mozjs/cursor.h b/src/mongo/scripting/mozjs/cursor.h index 3d3386f7bcc..a0190e6a359 100644 --- a/src/mongo/scripting/mozjs/cursor.h +++ b/src/mongo/scripting/mozjs/cursor.h @@ -47,12 +47,13 @@ struct CursorInfo : public BaseInfo { struct Functions { MONGO_DECLARE_JS_FUNCTION(close); MONGO_DECLARE_JS_FUNCTION(hasNext); + MONGO_DECLARE_JS_FUNCTION(isClosed); MONGO_DECLARE_JS_FUNCTION(next); MONGO_DECLARE_JS_FUNCTION(objsLeftInBatch); MONGO_DECLARE_JS_FUNCTION(readOnly); }; - static const JSFunctionSpec methods[6]; + static const JSFunctionSpec methods[7]; static const char* const className; static const unsigned classFlags = JSCLASS_HAS_PRIVATE; diff --git a/src/mongo/shell/collection.js b/src/mongo/shell/collection.js index 8d242a347a9..452a2361f30 100644 --- a/src/mongo/shell/collection.js +++ b/src/mongo/shell/collection.js @@ -1641,6 +1641,25 @@ DBCollection.prototype.latencyStats = function(options) { return this.aggregate([{$collStats: {latencyStats: options}}]); }; +DBCollection.prototype.watch = function(pipeline, options) { + pipeline = pipeline || []; + options = options || {}; + assert(pipeline instanceof Array, "'pipeline' argument must be an array"); + assert(options instanceof Object, "'options' argument must be an object"); + + let changeStreamStage = {fullDocument: options.fullDocument || "default"}; + delete options.fullDocument; + + if (options.hasOwnProperty("resumeAfter")) { + changeStreamStage.resumeAfter = options.resumeAfter; + delete options.resumeAfter; + } + + pipeline.unshift({$changeStream: changeStreamStage}); + // Pass options "batchSize", "collation" and "maxAwaitTimeMS" down to aggregate(). + return this.aggregate(pipeline, options); +}; + /** * PlanCache * Holds a reference to the collection. diff --git a/src/mongo/shell/db.js b/src/mongo/shell/db.js index a7e133df116..8ef40760efa 100644 --- a/src/mongo/shell/db.js +++ b/src/mongo/shell/db.js @@ -215,6 +215,9 @@ var DB; delete optcpy['useCursor']; } + const maxAwaitTimeMS = optcpy.maxAwaitTimeMS; + delete optcpy.maxAwaitTimeMS; + // Reassign the cleaned-up options. aggregateOptions = optcpy; @@ -263,7 +266,7 @@ var DB; batchSizeValue = cmdObj["cursor"]["batchSize"]; } - return new DBCommandCursor(this, res, batchSizeValue); + return new DBCommandCursor(this, res, batchSizeValue, maxAwaitTimeMS); } return res; diff --git a/src/mongo/shell/query.js b/src/mongo/shell/query.js index 6de7edb3661..431c3aa9455 100644 --- a/src/mongo/shell/query.js +++ b/src/mongo/shell/query.js @@ -681,6 +681,16 @@ DBQuery.prototype.close = function() { this._cursor.close(); }; +DBQuery.prototype.isClosed = function() { + this._exec(); + return this._cursor.isClosed(); +}; + +DBQuery.prototype.isExhausted = function() { + this._exec(); + return this._cursor.isClosed() && this._cursor.objsLeftInBatch() === 0; +}; + DBQuery.shellBatchSize = 20; /** @@ -697,7 +707,7 @@ DBQuery.Option = { partial: 0x80 }; -function DBCommandCursor(db, cmdResult, batchSize) { +function DBCommandCursor(db, cmdResult, batchSize, maxAwaitTimeMS) { if (cmdResult._mongo) { const newSession = new _DelegatingDriverSession(cmdResult._mongo, db.getSession()); db = newSession.getDatabase(db.getName()); @@ -713,6 +723,7 @@ function DBCommandCursor(db, cmdResult, batchSize) { this._useReadCommands = true; this._cursorid = cmdResult.cursor.id; this._batchSize = batchSize; + this._maxAwaitTimeMS = maxAwaitTimeMS; this._ns = cmdResult.cursor.ns; this._db = db; @@ -732,10 +743,27 @@ function DBCommandCursor(db, cmdResult, batchSize) { DBCommandCursor.prototype = {}; +/** + * Returns whether the cursor id is zero. + */ +DBCommandCursor.prototype.isClosed = function() { + if (this._useReadCommands) { + return bsonWoCompare({_: this._cursorid}, {_: NumberLong(0)}) === 0; + } + return this._cursor.isClosed(); +}; + +/** + * Returns whether the cursor has closed and has nothing in the batch. + */ +DBCommandCursor.prototype.isExhausted = function() { + return this.isClosed() && this.objsLeftInBatch() === 0; +}; + DBCommandCursor.prototype.close = function() { if (!this._useReadCommands) { this._cursor.close(); - } else if (this._cursorid != 0) { + } else if (bsonWoCompare({_: this._cursorid}, {_: NumberLong(0)}) !== 0) { var killCursorCmd = { killCursors: this._collName, cursors: [this._cursorid], @@ -764,6 +792,11 @@ DBCommandCursor.prototype._runGetMoreCommand = function() { getMoreCmd["batchSize"] = this._batchSize; } + // maxAwaitTimeMS is only supported when using read commands. + if (this._maxAwaitTimeMS) { + getMoreCmd.maxTimeMS = this._maxAwaitTimeMS; + } + // Deliver the getMore command, and check for errors in the response. var cmdRes = this._db.runCommand(getMoreCmd); if (cmdRes.ok != 1) { |