Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions packages/cli-repl/src/cli-repl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,11 +298,15 @@ class CliRepl {
// This checks for error instances.
// The writer gets called immediately by the internal `this.repl.eval`
// in case of errors.
if (result && result.message && typeof result.stack === 'string') {
this.bus.emit('mongosh:error', result);
if (result && (
(result.message !== undefined && typeof result.stack === 'string') ||
(result.code !== undefined && result.errmsg !== undefined)
)) {
this.shellEvaluator.revertState();

return formatOutput({ type: 'Error', value: result });
const output = { ...result, message: result.message || result.errmsg, name: result.name || 'MongoshInternalError' };
this.bus.emit('mongosh:error', output);
return formatOutput({ type: 'Error', value: output });
}

return formatOutput(result);
Expand Down
19 changes: 14 additions & 5 deletions packages/cli-repl/test/e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,20 @@ describe('e2e', function() {
client.close();
});

describe('error formatting', () => {
it('throws when a syntax error is encountered', async() => {
await shell.executeLine('<x');
shell.assertContainsError('SyntaxError: Unexpected token');
});
it('throws a runtime error', async() => {
await shell.executeLine('throw new Error(\'a errmsg\')');
shell.assertContainsError('Error: a errmsg');
});
it('recognizes a driver error as error', async() => {
await shell.executeLine('db.coll.initializeOrderedBulkOp().find({}).update({}, {}).execute()');
shell.assertContainsOutput('MongoshInternalError: multi update is not supported for replacement-style update');
});
});
it('throws multiline input with a single line string', async() => {
// this is an unterminated string constant and should throw, since it does
// not pass: https://www.ecma-international.org/ecma-262/#sec-line-terminators
Expand Down Expand Up @@ -169,11 +183,6 @@ describe('e2e', function() {
});
});
});
it('throws when a syntax error is encountered', async() => {
await shell.executeLine('<x');
shell.assertContainsError('SyntaxError: Unexpected token');
});

it('runs an unterminated function', async() => {
await shell.writeInputLine('function x () {\nconsole.log(\'y\')\n }');
shell.assertNoErrors();
Expand Down
101 changes: 101 additions & 0 deletions packages/i18n/src/locales/en_US.js
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,16 @@ const translations = {
description: 'returns the $latencyStats aggregation for the collection. Takes an options document with an optional boolean \'histograms\' field.',
example: 'db.latencyStats({ histograms: true })'
},
initializeUnorderedBulkOp: {
link: 'https://docs.mongodb.com/manual/reference/method/db.collection.initializeUnorderedBulkOp',
description: 'Initializes an unordered bulk command. Returns an instance of Bulk',
example: 'db.initializeUnorderedBulkOp()'
},
initializeOrderedBulkOp: {
link: 'https://docs.mongodb.com/manual/reference/method/db.collection.initializeOrderedBulkOp',
description: 'Initializes an ordered bulk command. Returns an instance of Bulk',
example: 'db.initializeOrderedBulkOp()'
}
}
}
},
Expand Down Expand Up @@ -1207,6 +1217,97 @@ const translations = {
},
attributes: {}
},
Bulk: {
help: {
link: 'https://docs.mongodb.com/manual/reference/method/Bulk',
description: 'Bulk operations builder used to construct a list of write operations to perform in bulk for a single collection. To instantiate the builder, use either the db.collection.initializeOrderedBulkOp() or the db.collection.initializeUnorderedBulkOp() method.',
attributes: {
insert: {
link: 'https://docs.mongodb.com/manual/reference/method/Bulk.insert/',
description: 'Adds an insert to the bulk operation.',
example: 'db.insert(<document>)'
},
execute: {
link: 'https://docs.mongodb.com/manual/reference/method/Bulk.execute/',
description: 'Executes the bulk operation.',
example: 'bulkOp.execute()',
},
find: {
link: 'https://docs.mongodb.com/manual/reference/method/Bulk.find/',
description: 'Adds a find to the bulk operation.',
example: 'bulkOp.find(<filter>)',
},
getOperations: {
link: 'https://docs.mongodb.com/manual/reference/method/Bulk.getOperations/',
description: 'Returns the batches executed by the bulk write.',
example: 'bulkOp.getOperations()',
},
tojson: {
link: 'https://docs.mongodb.com/manual/reference/method/Bulk.tojson/',
description: 'Returns a JSON document that contains the number of operations and batches in the Bulk() object.',
example: 'bulkOp.tojson()',
},
toString: {
link: 'https://docs.mongodb.com/manual/reference/method/Bulk.toString/',
description: 'Returns as a string a JSON document that contains the number of operations and batches in the Bulk() object.',
example: 'bulkOp.toString()',
}
}
}
},
BulkFindOp: {
help: {
link: 'https://docs.mongodb.com/manual/reference/method/Bulk.find',
description: 'Bulk operations builder returned after Bulk.find()',
attributes: {
'arrayFilters': {
link: 'https://docs.mongodb.com/manual/reference/method/Bulk.find.arrayFilters/',
description: 'Adds an arrayFilter to the bulk operation.',
example: 'bulkOp.find(...).arrayFilters(<array of filters)',
},
'hint': {
link: 'https://docs.mongodb.com/manual/reference/method/Bulk.find.hint/',
description: 'Adds an hint to the bulk operation.',
example: 'bulkOp.find(...).hint(<hintd document>)',
},
'collation': {
link: 'https://docs.mongodb.com/manual/reference/method/Bulk.find.collation/',
description: 'Not currently implemented, use db.collection.bulkWrite as an alternative',
example: 'bulkOp.find(...).collation(<collation doc>)',
},
'remove': {
link: 'https://docs.mongodb.com/manual/reference/method/Bulk.find.remove/',
description: 'Adds an remove to the bulk operation.',
example: 'bulkOp.find(...).remove()',
},
'removeOne': {
link: 'https://docs.mongodb.com/manual/reference/method/Bulk.find.removeOne/',
description: 'Adds an removeOne to the bulk operation.',
example: 'bulkOp.find(...).removeOne()',
},
'replaceOne': {
link: 'https://docs.mongodb.com/manual/reference/method/Bulk.find.replaceOne/',
description: 'Adds an replaceOne to the bulk operation.',
example: 'bulkOp.find(...).replaceOne(<document>)',
},
'updateOne': {
link: 'https://docs.mongodb.com/manual/reference/method/Bulk.find.updateOne/',
description: 'Adds an updateOne to the bulk operation.',
example: 'bulkOp.find(...).updateOne(<document>)',
},
'update': {
link: 'https://docs.mongodb.com/manual/reference/method/Bulk.find.update/',
description: 'Adds an update to the bulk operation.',
example: 'bulkOp.find(...).update(<document>)',
},
'upsert': {
link: 'https://docs.mongodb.com/manual/reference/method/Bulk.find.upsert/',
description: 'Adds an upsert to the bulk operation updates for this find(...).',
example: 'bulkOp.find(...).upsert()',
}
}
}
}
}
},
'transport-browser': {
Expand Down
109 changes: 109 additions & 0 deletions packages/service-provider-core/src/bulk.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import Document from './document';

export interface BulkBatch {
originalZeroIndex: number;
batchType: number;
operations: any[];
[key: string]: any;
}

export interface DriverBulkResult {
result: {
ok: boolean;
/**
* The number of documents inserted.
*/
nInserted: number;

/**
* The number of existing documents selected for update or replacement.
*/
nMatched: number;

/**
* The number of existing documents updated or replaced.
*/
nModified: number;

/**
* The number of documents removed.
*/
nRemoved: number;

/**
* The number of upserted documents.
*/
nUpserted: number;

/**
* Ids of upserted documents.
*/
upserted: {[index: number]: any};

/**
* Ids of inserted documents.
*/
insertedIds: {[index: number]: any};
};
}

export interface ServiceProviderBulkFindOp {
/**
* Add a remove operation
*/
remove(): ServiceProviderBulkOp;

/**
* Add a removeOne operation
*/
removeOne(): ServiceProviderBulkOp;

/**
* Add a replaceOne operation
*/
replaceOne(replacement: Document): ServiceProviderBulkOp;

/**
* Add a updateOne operation
*/
updateOne(update: Document): ServiceProviderBulkOp;

/**
* Add a update operation
*/
update(update: Document): ServiceProviderBulkOp;

/**
* Make subsequent update operations upsert: true
*/
upsert(): ServiceProviderBulkFindOp;
}

export default interface ServiceProviderBulkOp {
/**
* Internal state
*/
s: {
batches: BulkBatch[];
currentUpdateBatch: BulkBatch;
currentRemoveBatch: BulkBatch;
currentInsertBatch: BulkBatch;
currentBatch: BulkBatch;
};

/**
* Execute the operation.
*/
execute(): Promise<DriverBulkResult>;

/**
* Find
*/
find(document: Document): ServiceProviderBulkFindOp;

/**
* Insert
*/
insert(document: Document): ServiceProviderBulkOp;

}
6 changes: 5 additions & 1 deletion packages/service-provider-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import CliOptions from './cli-options';
import generateUri, { Scheme } from './uri-generator';
const DEFAULT_DB = 'test';
import bson from 'bson';
import ServiceProviderBulkOp, { ServiceProviderBulkFindOp, BulkBatch } from './bulk';

export {
ServiceProvider,
Expand All @@ -37,5 +38,8 @@ export {
Scheme,
DEFAULT_DB,
ServiceProviderCore,
bson
bson,
ServiceProviderBulkFindOp,
ServiceProviderBulkOp,
BulkBatch
};
17 changes: 17 additions & 0 deletions packages/service-provider-core/src/writable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -400,5 +400,22 @@ export default interface Writable {
newName: string,
options?: Document,
dbOptions?: DatabaseOptions): Promise<Result>;

/**
* Initialize a bulk operation.
*
* @param dbName
* @param collName
* @param ordered
* @param options
* @param dbOptions
*/
initializeBulkOp(
dbName: string,
collName: string,
ordered: boolean,
options?: any,
dbOptions?: any
): Promise<any>;
}

13 changes: 13 additions & 0 deletions packages/service-provider-server/src/cli-service-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1052,6 +1052,19 @@ class CliServiceProvider extends ServiceProviderCore implements ServiceProvider
};
}
}

async initializeBulkOp(
dbName: string,
collName: string,
ordered: boolean,
options = {},
dbOptions?: any
): Promise<any> {
if (ordered) {
return await this.db(dbName, dbOptions).collection(collName).initializeOrderedBulkOp(options);
}
return await this.db(dbName, dbOptions).collection(collName).initializeUnorderedBulkOp(options);
}
}

export default CliServiceProvider;
Loading