Skip to content

Commit

Permalink
feat: remove callbacks from gridfs
Browse files Browse the repository at this point in the history
  • Loading branch information
nbbeeken committed Jan 20, 2023
1 parent 51b0649 commit bfaf3c9
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 70 deletions.
20 changes: 6 additions & 14 deletions src/gridfs/download.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,30 +182,22 @@ export class GridFSBucketReadStream extends Readable implements NodeJS.ReadableS
* Marks this stream as aborted (will never push another `data` event)
* and kills the underlying cursor. Will emit the 'end' event, and then
* the 'close' event once the cursor is successfully killed.
*
* @param callback - called when the cursor is successfully closed or an error occurred.
*/
abort(callback?: Callback<void>): void {
async abort(): Promise<void> {
this.push(null);
this.destroyed = true;
if (this.s.cursor) {
this.s.cursor.close().then(
() => {
this.emit(GridFSBucketReadStream.CLOSE);
callback?.();
},
error => {
this.emit(GridFSBucketReadStream.CLOSE);
callback?.(error);
}
);
try {
await this.s.cursor.close();
} finally {
this.emit(GridFSBucketReadStream.CLOSE);
}
} else {
if (!this.s.init) {
// If not initialized, fire close event because we will never
// get a cursor
this.emit(GridFSBucketReadStream.CLOSE);
}
callback && callback();
}
}
}
Expand Down
58 changes: 21 additions & 37 deletions src/gridfs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import type { Logger } from '../logger';
import { Filter, TypedEventEmitter } from '../mongo_types';
import type { ReadPreference } from '../read_preference';
import type { Sort } from '../sort';
import { Callback, maybeCallback } from '../utils';
import { WriteConcern, WriteConcernOptions } from '../write_concern';
import type { FindOptions } from './../operations/find';
import {
Expand Down Expand Up @@ -140,22 +139,17 @@ export class GridFSBucket extends TypedEventEmitter<GridFSBucketEvents> {
*
* @param id - The id of the file doc
*/
delete(id: ObjectId): Promise<void>;
/** @deprecated Callbacks are deprecated and will be removed in the next major version. See [mongodb-legacy](https://github.com/mongodb-js/nodejs-mongodb-legacy) for migration assistance */
delete(id: ObjectId, callback: Callback<void>): void;
delete(id: ObjectId, callback?: Callback<void>): Promise<void> | void {
return maybeCallback(async () => {
const { deletedCount } = await this.s._filesCollection.deleteOne({ _id: id });

// Delete orphaned chunks before returning FileNotFound
await this.s._chunksCollection.deleteMany({ files_id: id });

if (deletedCount === 0) {
// TODO(NODE-3483): Replace with more appropriate error
// Consider creating new error MongoGridFSFileNotFoundError
throw new MongoRuntimeError(`File not found for id ${id}`);
}
}, callback);
async delete(id: ObjectId): Promise<void> {
const { deletedCount } = await this.s._filesCollection.deleteOne({ _id: id });

// Delete orphaned chunks before returning FileNotFound
await this.s._chunksCollection.deleteMany({ files_id: id });

if (deletedCount === 0) {
// TODO(NODE-3483): Replace with more appropriate error
// Consider creating new error MongoGridFSFileNotFoundError
throw new MongoRuntimeError(`File not found for id ${id}`);
}
}

/** Convenience wrapper around find on the files collection */
Expand Down Expand Up @@ -201,29 +195,19 @@ export class GridFSBucket extends TypedEventEmitter<GridFSBucketEvents> {
* @param id - the id of the file to rename
* @param filename - new name for the file
*/
rename(id: ObjectId, filename: string): Promise<void>;
/** @deprecated Callbacks are deprecated and will be removed in the next major version. See [mongodb-legacy](https://github.com/mongodb-js/nodejs-mongodb-legacy) for migration assistance */
rename(id: ObjectId, filename: string, callback: Callback<void>): void;
rename(id: ObjectId, filename: string, callback?: Callback<void>): Promise<void> | void {
return maybeCallback(async () => {
const filter = { _id: id };
const update = { $set: { filename } };
const { matchedCount } = await this.s._filesCollection.updateOne(filter, update);
if (matchedCount === 0) {
throw new MongoRuntimeError(`File with id ${id} not found`);
}
}, callback);
async rename(id: ObjectId, filename: string): Promise<void> {
const filter = { _id: id };
const update = { $set: { filename } };
const { matchedCount } = await this.s._filesCollection.updateOne(filter, update);
if (matchedCount === 0) {
throw new MongoRuntimeError(`File with id ${id} not found`);
}
}

/** Removes this bucket's files collection, followed by its chunks collection. */
drop(): Promise<void>;
/** @deprecated Callbacks are deprecated and will be removed in the next major version. See [mongodb-legacy](https://github.com/mongodb-js/nodejs-mongodb-legacy) for migration assistance */
drop(callback: Callback<void>): void;
drop(callback?: Callback<void>): Promise<void> | void {
return maybeCallback(async () => {
await this.s._filesCollection.drop();
await this.s._chunksCollection.drop();
}, callback);
async drop(): Promise<void> {
await this.s._filesCollection.drop();
await this.s._chunksCollection.drop();
}

/** Get the Db scoped logger. */
Expand Down
31 changes: 12 additions & 19 deletions src/gridfs/upload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { Document } from '../bson';
import { ObjectId } from '../bson';
import type { Collection } from '../collection';
import { AnyError, MongoAPIError, MONGODB_ERROR_CODES, MongoError } from '../error';
import { Callback, maybeCallback } from '../utils';
import type { Callback } from '../utils';
import type { WriteConcernOptions } from '../write_concern';
import { WriteConcern } from './../write_concern';
import type { GridFSFile } from './download';
Expand Down Expand Up @@ -144,27 +144,20 @@ export class GridFSBucketWriteStream extends Writable implements NodeJS.Writable
/**
* Places this write stream into an aborted state (all future writes fail)
* and deletes all chunks that have already been written.
*
* @param callback - called when chunks are successfully removed or error occurred
*/
abort(): Promise<void>;
/** @deprecated Callbacks are deprecated and will be removed in the next major version. See [mongodb-legacy](https://github.com/mongodb-js/nodejs-mongodb-legacy) for migration assistance */
abort(callback: Callback<void>): void;
abort(callback?: Callback<void>): Promise<void> | void {
return maybeCallback(async () => {
if (this.state.streamEnd) {
// TODO(NODE-3485): Replace with MongoGridFSStreamClosed
throw new MongoAPIError('Cannot abort a stream that has already completed');
}
async abort(): Promise<void> {
if (this.state.streamEnd) {
// TODO(NODE-3485): Replace with MongoGridFSStreamClosed
throw new MongoAPIError('Cannot abort a stream that has already completed');
}

if (this.state.aborted) {
// TODO(NODE-3485): Replace with MongoGridFSStreamClosed
throw new MongoAPIError('Cannot call abort() on a stream twice');
}
if (this.state.aborted) {
// TODO(NODE-3485): Replace with MongoGridFSStreamClosed
throw new MongoAPIError('Cannot call abort() on a stream twice');
}

this.state.aborted = true;
await this.chunks.deleteMany({ files_id: this.id });
}, callback);
this.state.aborted = true;
await this.chunks.deleteMany({ files_id: this.id });
}

/**
Expand Down

0 comments on commit bfaf3c9

Please sign in to comment.