Skip to content

Commit

Permalink
feat: reimplement clone for find and aggregate cursors
Browse files Browse the repository at this point in the history
  • Loading branch information
mbroadst committed Dec 2, 2020
1 parent 8f24e65 commit 7bbc569
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 24 deletions.
6 changes: 6 additions & 0 deletions src/change_stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,12 @@ export class ChangeStreamCursor extends AbstractCursor {
}
}

clone(): ChangeStreamCursor {
return new ChangeStreamCursor(this.topology, this.namespace, this.pipeline, {
...this.cursorOptions
});
}

_initialize(session: ClientSession, callback: Callback<ExecutionResult>): void {
const aggregateOperation = new AggregateOperation(
{ s: { namespace: this.namespace } },
Expand Down
5 changes: 5 additions & 0 deletions src/cursor/abstract_cursor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,11 @@ export abstract class AbstractCursor extends EventEmitter {
}
}

/**
* Returns a new uninitialized copy of this cursor, with options matching those that have been set on the current instance
*/
abstract clone(): AbstractCursor;

/* @internal */
abstract _initialize(
session: ClientSession | undefined,
Expand Down
7 changes: 7 additions & 0 deletions src/cursor/aggregation_cursor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ export class AggregationCursor extends AbstractCursor {
return this[kPipeline];
}

clone(): AggregationCursor {
return new AggregationCursor(this[kParent], this.topology, this.namespace, this[kPipeline], {
...this[kOptions],
...this.cursorOptions
});
}

/** @internal */
_initialize(session: ClientSession | undefined, callback: Callback<ExecutionResult>): void {
const aggregateOperation = new AggregateOperation(this[kParent], this[kPipeline], {
Expand Down
7 changes: 7 additions & 0 deletions src/cursor/find_cursor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ export class FindCursor extends AbstractCursor {
}
}

clone(): FindCursor {
return new FindCursor(this.topology, this.namespace, this[kFilter], {
...this[kBuiltOptions],
...this.cursorOptions
});
}

/** @internal */
_initialize(session: ClientSession | undefined, callback: Callback<ExecutionResult>): void {
const findOperation = new FindOperation(undefined, this.namespace, this[kFilter], {
Expand Down
7 changes: 7 additions & 0 deletions src/operations/indexes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,13 @@ export class ListIndexesCursor extends AbstractCursor {
this.options = options;
}

clone(): ListIndexesCursor {
return new ListIndexesCursor(this.parent, {
...this.options,
...this.cursorOptions
});
}

/** @internal */
_initialize(session: ClientSession | undefined, callback: Callback<ExecutionResult>): void {
const operation = new ListIndexesOperation(this.parent, {
Expand Down
7 changes: 7 additions & 0 deletions src/operations/list_collections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,13 @@ export class ListCollectionsCursor extends AbstractCursor {
this.options = options;
}

clone(): ListCollectionsCursor {
return new ListCollectionsCursor(this.parent, this.filter, {
...this.options,
...this.cursorOptions
});
}

_initialize(session: ClientSession | undefined, callback: Callback<ExecutionResult>): void {
const operation = new ListCollectionsOperation(this.parent, this.filter, {
...this.cursorOptions,
Expand Down
88 changes: 64 additions & 24 deletions test/functional/abstract_cursor.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ describe('AbstractCursor', function () {
before(
withClientV2((client, done) => {
const docs = [{ a: 1 }, { a: 2 }, { a: 3 }, { a: 4 }, { a: 5 }, { a: 6 }];
const coll = client.db().collection('find_cursor');
const coll = client.db().collection('abstract_cursor');
const tryNextColl = client.db().collection('try_next');
coll.drop(() => tryNextColl.drop(() => coll.insertMany(docs, done)));
})
Expand All @@ -35,7 +35,7 @@ describe('AbstractCursor', function () {
const commands = [];
client.on('commandStarted', filterForCommands(['getMore'], commands));

const coll = client.db().collection('find_cursor');
const coll = client.db().collection('abstract_cursor');
const cursor = coll.find({}, { batchSize: 2 });
this.defer(() => cursor.close());

Expand All @@ -56,7 +56,7 @@ describe('AbstractCursor', function () {
const commands = [];
client.on('commandStarted', filterForCommands(['killCursors'], commands));

const coll = client.db().collection('find_cursor');
const coll = client.db().collection('abstract_cursor');
const cursor = coll.find({}, { batchSize: 2 });
cursor.next(err => {
expect(err).to.not.exist;
Expand All @@ -75,7 +75,7 @@ describe('AbstractCursor', function () {
const commands = [];
client.on('commandStarted', filterForCommands(['killCursors'], commands));

const coll = client.db().collection('find_cursor');
const coll = client.db().collection('abstract_cursor');
const cursor = coll.find({}, { batchSize: 2 });
cursor.toArray(err => {
expect(err).to.not.exist;
Expand All @@ -95,7 +95,7 @@ describe('AbstractCursor', function () {
const commands = [];
client.on('commandStarted', filterForCommands(['killCursors'], commands));

const coll = client.db().collection('find_cursor');
const coll = client.db().collection('abstract_cursor');
const cursor = coll.find({}, { batchSize: 2 });
cursor.close(err => {
expect(err).to.not.exist;
Expand All @@ -110,7 +110,7 @@ describe('AbstractCursor', function () {
it(
'should iterate each document in a cursor',
withClientV2(function (client, done) {
const coll = client.db().collection('find_cursor');
const coll = client.db().collection('abstract_cursor');
const cursor = coll.find({}, { batchSize: 2 });

const bag = [];
Expand Down Expand Up @@ -160,45 +160,85 @@ describe('AbstractCursor', function () {
);
});

context('#rewind', function () {
beforeEach(
context('#clone', function () {
it(
'should clone a find cursor',
withClientV2(function (client, done) {
const coll = client.db().collection('rewind');
coll.drop(() => {
coll.insertMany([{}, {}], err => {
const coll = client.db().collection('abstract_cursor');
const cursor = coll.find({});
this.defer(() => cursor.close());

cursor.toArray((err, docs) => {
expect(err).to.not.exist;
expect(docs).to.have.length(6);
expect(cursor).property('closed').to.be.true;

const clonedCursor = cursor.clone();
this.defer(() => clonedCursor.close());

clonedCursor.toArray((err, docs) => {
expect(err).to.not.exist;
expect(docs).to.have.length(6);
expect(clonedCursor).property('closed').to.be.true;
done();
});
});
})
);

it(
'should clone an aggregate cursor',
withClientV2(function (client, done) {
const coll = client.db().collection('abstract_cursor');
const cursor = coll.aggregate([{ $match: {} }]);
this.defer(() => cursor.close());

cursor.toArray((err, docs) => {
expect(err).to.not.exist;
expect(docs).to.have.length(6);
expect(cursor).property('closed').to.be.true;

const clonedCursor = cursor.clone();
this.defer(() => clonedCursor.close());

clonedCursor.toArray((err, docs) => {
expect(err).to.not.exist;
expect(docs).to.have.length(6);
expect(clonedCursor).property('closed').to.be.true;
done();
});
});
})
);
});

context('#rewind', function () {
it(
'should rewind a cursor',
withClientV2(function (client, done) {
const coll = client.db().collection('rewind');
const coll = client.db().collection('abstract_cursor');
const cursor = coll.find({});
this.defer(() => cursor.close());

cursor.toArray((err, docs) => {
expect(err).to.not.exist;
expect(docs).to.have.length(2);
expect(docs).to.have.length(6);

cursor.rewind();
cursor.toArray((err, docs) => {
expect(err).to.not.exist;
expect(docs).to.have.length(2);
expect(docs).to.have.length(6);

done();
});
});
})
);

it(
'should end an implicit session on rewind',
withClientV2(function (client, done) {
const coll = client.db().collection('rewind');
it('should end an implicit session on rewind', {
metadata: { requires: { mongodb: '>=3.6' } },
test: withClientV2(function (client, done) {
const coll = client.db().collection('abstract_cursor');
const cursor = coll.find({}, { batchSize: 1 });
this.defer(() => cursor.close());

Expand All @@ -213,12 +253,12 @@ describe('AbstractCursor', function () {
done();
});
})
);
});

it(
'should not end an explicit session on rewind',
withClientV2(function (client, done) {
const coll = client.db().collection('rewind');
it('should not end an explicit session on rewind', {
metadata: { requires: { mongodb: '>=3.6' } },
test: withClientV2(function (client, done) {
const coll = client.db().collection('abstract_cursor');
const session = client.startSession();

const cursor = coll.find({}, { batchSize: 1, session });
Expand All @@ -236,6 +276,6 @@ describe('AbstractCursor', function () {
session.endSession(done);
});
})
);
});
});
});

0 comments on commit 7bbc569

Please sign in to comment.