summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mongo/scripting/mozjs/cursor.cpp14
-rw-r--r--src/mongo/scripting/mozjs/cursor.h3
-rw-r--r--src/mongo/shell/collection.js19
-rw-r--r--src/mongo/shell/db.js5
-rw-r--r--src/mongo/shell/query.js37
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) {