Skip to content

feat(NODE-4877): Add support for useBigInt64 #3519

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 33 commits into from
Feb 23, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
d54383d
feat(NODE-4950)!: remove bson-ext import and squash commits
nbbeeken Jan 13, 2023
6eea5be
Merge branch 'main' into NODE-4877/add-support-for-BSON-useBigInt64-flag
W-A-James Feb 8, 2023
9f623a7
ci(NODE-4877): Fix generate_evergreen_tasks.js
W-A-James Feb 8, 2023
ddda8f8
test(NODE-4877): Work on resolving review comments
W-A-James Feb 15, 2023
6ac4651
test(NODE-4877): Change test name
W-A-James Feb 15, 2023
330a27a
test(NODE-4877): Add new test
W-A-James Feb 15, 2023
90a5cea
test(NODE-4877): add new tests
W-A-James Feb 16, 2023
2e40c2b
test(NODE-4877): Update tests
W-A-James Feb 17, 2023
cde8f0a
fix(NODE-4877): Add validation for bson options
W-A-James Feb 17, 2023
bbf39e8
fix(NODE-4877): revert unneeded change
W-A-James Feb 17, 2023
6b7ed65
fix(NODE-4877): Revert unneeded change
W-A-James Feb 17, 2023
6ca31e8
style(NODE-4877): eslint
W-A-James Feb 17, 2023
ddcc45b
Merge branch 'main' into NODE-4877/add-support-for-BSON-useBigInt64-flag
W-A-James Feb 17, 2023
16153b3
test(NODE-4877): Exclude tests from single servers
W-A-James Feb 17, 2023
733ce4a
fix(NODE-4877): Undo unneeded change
W-A-James Feb 17, 2023
c5c94ae
style(NODE-4877): Revert unneeded style change
W-A-James Feb 21, 2023
c7ad82c
fix(NODE-4877): Revert unneeded change to unused function
W-A-James Feb 21, 2023
f29d8f5
chore(NODE-4877): Bump bson version
W-A-James Feb 21, 2023
e5b0430
test(NODE-4877): Make test more idiomatic
W-A-James Feb 21, 2023
5073ce3
fix(NODE-4877): Add bigint to mongo IntegerType and NestedPaths
W-A-James Feb 21, 2023
4f50116
test(NODE-4877): Remove unneeded NOTE comment
W-A-James Feb 21, 2023
35c7a2c
test(NODE-4877): Add tests to check that BSONErrors get thrown
W-A-James Feb 21, 2023
01447c7
fix(NODE-4877): Add check for existence of options.promoteLongs and o…
W-A-James Feb 21, 2023
7e903a3
fix(NODE-4877): fix condition
W-A-James Feb 21, 2023
f178c82
test(NODE-4877): remove setting promoteValues and promoteLongs
W-A-James Feb 21, 2023
61e1370
test(NODE-4877): Remove explicit calls to connect
W-A-James Feb 21, 2023
efcf0b9
style(NODE-4877): eslint
W-A-James Feb 21, 2023
3485472
Update test/integration/change-streams/change_stream.test.ts
W-A-James Feb 22, 2023
3e3aef3
test(NODE-4877): test reorganization
W-A-James Feb 22, 2023
f33339f
test(NODE-4877): Add operation-level option superceding tests
W-A-James Feb 22, 2023
c8c0b36
test(NODE-4877): Add type annotations
W-A-James Feb 22, 2023
e4dd63a
Merge branch 'main' into NODE-4877/add-support-for-BSON-useBigInt64-flag
W-A-James Feb 22, 2023
4e3469d
test(NODE-4877): remove unneeded import
W-A-James Feb 22, 2023
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,4 @@ etc/docs/build
!docs/**/*.png
!docs/**/*.css
!docs/**/*.js
.nvmrc
4 changes: 3 additions & 1 deletion src/bson.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ export interface BSONSerializeOptions
| 'allowObjectSmallerThanBufferSize'
| 'index'
| 'validation'
| 'useBigInt64'
> {
/**
* Enabling the raw option will return a [Node.js Buffer](https://nodejs.org/api/buffer.html)
Expand Down Expand Up @@ -67,6 +66,7 @@ export interface BSONSerializeOptions
export function pluckBSONSerializeOptions(options: BSONSerializeOptions): BSONSerializeOptions {
const {
fieldsAsRaw,
useBigInt64,
promoteValues,
promoteBuffers,
promoteLongs,
Expand All @@ -78,6 +78,7 @@ export function pluckBSONSerializeOptions(options: BSONSerializeOptions): BSONSe
} = options;
return {
fieldsAsRaw,
useBigInt64,
promoteValues,
promoteBuffers,
promoteLongs,
Expand All @@ -102,6 +103,7 @@ export function resolveBSONOptions(
const parentOptions = parent?.bsonOptions;
return {
raw: options?.raw ?? parentOptions?.raw ?? false,
useBigInt64: options?.useBigInt64 ?? parentOptions?.useBigInt64 ?? false,
promoteLongs: options?.promoteLongs ?? parentOptions?.promoteLongs ?? true,
promoteValues: options?.promoteValues ?? parentOptions?.promoteValues ?? true,
promoteBuffers: options?.promoteBuffers ?? parentOptions?.promoteBuffers ?? false,
Expand Down
1 change: 1 addition & 0 deletions src/cmap/auth/mongodb_aws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const AWS_RELATIVE_URI = 'http://169.254.170.2';
const AWS_EC2_URI = 'http://169.254.169.254';
const AWS_EC2_PATH = '/latest/meta-data/iam/security-credentials';
const bsonOptions: BSONSerializeOptions = {
useBigInt64: false,
promoteLongs: true,
promoteValues: true,
promoteBuffers: false,
Expand Down
10 changes: 10 additions & 0 deletions src/cmap/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ export class Response {
queryFailure?: boolean;
shardConfigStale?: boolean;
awaitCapable?: boolean;
useBigInt64: boolean;
promoteLongs: boolean;
promoteValues: boolean;
promoteBuffers: boolean;
Expand All @@ -320,6 +321,7 @@ export class Response {
this.raw = message;
this.data = msgBody;
this.opts = opts ?? {
useBigInt64: false,
promoteLongs: true,
promoteValues: true,
promoteBuffers: false,
Expand All @@ -334,6 +336,7 @@ export class Response {
this.fromCompressed = msgHeader.fromCompressed;

// Flag values
this.useBigInt64 = typeof this.opts.useBigInt64 === 'boolean' ? this.opts.useBigInt64 : false;
this.promoteLongs = typeof this.opts.promoteLongs === 'boolean' ? this.opts.promoteLongs : true;
this.promoteValues =
typeof this.opts.promoteValues === 'boolean' ? this.opts.promoteValues : true;
Expand All @@ -354,6 +357,7 @@ export class Response {
// Allow the return of raw documents instead of parsing
const raw = options.raw || false;
const documentsReturnedIn = options.documentsReturnedIn || null;
const useBigInt64 = options.useBigInt64 ?? this.opts.useBigInt64;
const promoteLongs = options.promoteLongs ?? this.opts.promoteLongs;
const promoteValues = options.promoteValues ?? this.opts.promoteValues;
const promoteBuffers = options.promoteBuffers ?? this.opts.promoteBuffers;
Expand All @@ -362,6 +366,7 @@ export class Response {

// Set up the options
const _options: BSONSerializeOptions = {
useBigInt64,
promoteLongs,
promoteValues,
promoteBuffers,
Expand Down Expand Up @@ -590,6 +595,7 @@ export class BinMsg {
checksumPresent: boolean;
moreToCome: boolean;
exhaustAllowed: boolean;
useBigInt64: boolean;
promoteLongs: boolean;
promoteValues: boolean;
promoteBuffers: boolean;
Expand All @@ -607,6 +613,7 @@ export class BinMsg {
this.raw = message;
this.data = msgBody;
this.opts = opts ?? {
useBigInt64: false,
promoteLongs: true,
promoteValues: true,
promoteBuffers: false,
Expand All @@ -625,6 +632,7 @@ export class BinMsg {
this.checksumPresent = (this.responseFlags & OPTS_CHECKSUM_PRESENT) !== 0;
this.moreToCome = (this.responseFlags & OPTS_MORE_TO_COME) !== 0;
this.exhaustAllowed = (this.responseFlags & OPTS_EXHAUST_ALLOWED) !== 0;
this.useBigInt64 = typeof this.opts.useBigInt64 === 'boolean' ? this.opts.useBigInt64 : false;
this.promoteLongs = typeof this.opts.promoteLongs === 'boolean' ? this.opts.promoteLongs : true;
this.promoteValues =
typeof this.opts.promoteValues === 'boolean' ? this.opts.promoteValues : true;
Expand All @@ -648,6 +656,7 @@ export class BinMsg {
// Allow the return of raw documents instead of parsing
const raw = options.raw || false;
const documentsReturnedIn = options.documentsReturnedIn || null;
const useBigInt64 = options.useBigInt64 ?? this.opts.useBigInt64;
const promoteLongs = options.promoteLongs ?? this.opts.promoteLongs;
const promoteValues = options.promoteValues ?? this.opts.promoteValues;
const promoteBuffers = options.promoteBuffers ?? this.opts.promoteBuffers;
Expand All @@ -656,6 +665,7 @@ export class BinMsg {

// Set up the options
const bsonOptions: BSONSerializeOptions = {
useBigInt64,
promoteLongs,
promoteValues,
promoteBuffers,
Expand Down
1 change: 1 addition & 0 deletions src/cmap/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,7 @@ function write(
command: !!options.command,

// for BSON parsing
useBigInt64: typeof options.useBigInt64 === 'boolean' ? options.useBigInt64 : false,
promoteLongs: typeof options.promoteLongs === 'boolean' ? options.promoteLongs : true,
promoteValues: typeof options.promoteValues === 'boolean' ? options.promoteValues : true,
promoteBuffers: typeof options.promoteBuffers === 'boolean' ? options.promoteBuffers : false,
Expand Down
1 change: 1 addition & 0 deletions src/cmap/wire_protocol/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export function applyCommonQueryOptions(
): CommandOptions {
Object.assign(queryOptions, {
raw: typeof options.raw === 'boolean' ? options.raw : false,
useBigInt64: typeof options.useBigInt64 === 'boolean' ? options.useBigInt64 : false,
promoteLongs: typeof options.promoteLongs === 'boolean' ? options.promoteLongs : true,
promoteValues: typeof options.promoteValues === 'boolean' ? options.promoteValues : true,
promoteBuffers: typeof options.promoteBuffers === 'boolean' ? options.promoteBuffers : false,
Expand Down
3 changes: 3 additions & 0 deletions src/connection_string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -945,6 +945,9 @@ export const OPTIONS = {
promoteValues: {
type: 'boolean'
},
useBigInt64: {
type: 'boolean'
},
proxyHost: {
type: 'string'
},
Expand Down
4 changes: 4 additions & 0 deletions src/cursor/abstract_cursor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,8 @@ export abstract class AbstractCursor<
this[kId] =
typeof response.cursor.id === 'number'
? Long.fromNumber(response.cursor.id)
: typeof response.cursor.id === 'bigint'
? Long.fromBigInt(response.cursor.id)
: response.cursor.id;

if (response.cursor.ns) {
Expand Down Expand Up @@ -741,6 +743,8 @@ export function next<T>(
const cursorId =
typeof response.cursor.id === 'number'
? Long.fromNumber(response.cursor.id)
: typeof response.cursor.id === 'bigint'
? Long.fromBigInt(response.cursor.id)
: response.cursor.id;

cursor[kDocuments].pushMany(response.cursor.nextBatch);
Expand Down
1 change: 1 addition & 0 deletions src/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ const DB_OPTIONS_ALLOW_LIST = [
'readConcern',
'retryMiliSeconds',
'numberOfRetries',
'useBigInt64',
'promoteBuffers',
'promoteLongs',
'bsonRegExp',
Expand Down
1 change: 1 addition & 0 deletions src/operations/create_collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const ILLEGAL_COMMAND_FIELDS = new Set([
'writeConcern',
'raw',
'fieldsAsRaw',
'useBigInt64',
'promoteLongs',
'promoteValues',
'promoteBuffers',
Expand Down
7 changes: 6 additions & 1 deletion src/sdam/monitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ export class Monitor extends TypedEventEmitter<MonitorEvents> {
// force BSON serialization options
{
raw: false,
useBigInt64: false,
promoteLongs: true,
promoteValues: true,
promoteBuffers: true
Expand Down Expand Up @@ -371,7 +372,11 @@ function makeTopologyVersion(tv: TopologyVersion) {
processId: tv.processId,
// tests mock counter as just number, but in a real situation counter should always be a Long
// TODO(NODE-2674): Preserve int64 sent from MongoDB
counter: Long.isLong(tv.counter) ? tv.counter : Long.fromNumber(tv.counter)
counter: Long.isLong(tv.counter)
? tv.counter
: typeof tv.counter === 'bigint'
? Long.fromBigInt(tv.counter)
: Long.fromNumber(tv.counter)
};
}

Expand Down
8 changes: 7 additions & 1 deletion src/sdam/server_description.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,8 +255,14 @@ export function compareTopologyVersion(
// TODO(NODE-2674): Preserve int64 sent from MongoDB
const currentCounter = Long.isLong(currentTv.counter)
? currentTv.counter
: typeof currentTv.counter === 'bigint'
? Long.fromBigInt(currentTv.counter)
: Long.fromNumber(currentTv.counter);
const newCounter = Long.isLong(newTv.counter) ? newTv.counter : Long.fromNumber(newTv.counter);
const newCounter = Long.isLong(newTv.counter)
? newTv.counter
: typeof newTv.counter === 'bigint'
? Long.fromBigInt(newTv.counter)
: Long.fromNumber(newTv.counter);

return currentCounter.compare(newCounter);
}
16 changes: 14 additions & 2 deletions src/sessions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,8 @@ export class ClientSession extends TypedEventEmitter<ClientSessionEvents> {
if (
!clusterTime.signature ||
clusterTime.signature.hash?._bsontype !== 'Binary' ||
(typeof clusterTime.signature.keyId !== 'number' &&
(typeof clusterTime.signature.keyId !== 'bigint' &&
typeof clusterTime.signature.keyId !== 'number' &&
clusterTime.signature.keyId?._bsontype !== 'Long') // apparently we decode the key to number?
) {
throw new MongoInvalidArgumentError(
Expand Down Expand Up @@ -971,7 +972,18 @@ export function applySession(
serverSession.txnNumber += session[kTxnNumberIncrement];
session[kTxnNumberIncrement] = 0;
// TODO(NODE-2674): Preserve int64 sent from MongoDB
command.txnNumber = Long.fromNumber(serverSession.txnNumber);
let txnNumber: Long;
switch (typeof serverSession.txnNumber) {
case 'number':
txnNumber = Long.fromNumber(serverSession.txnNumber);
break;
case 'bigint':
txnNumber = Long.fromBigInt(serverSession.txnNumber);
break;
default:
throw new MongoServerError({ message: 'HELP' });
}
command.txnNumber = txnNumber;
}

if (!inTxnOrTxnCommand) {
Expand Down
10 changes: 6 additions & 4 deletions test/integration/change-streams/change_stream.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,12 +162,14 @@ describe('Change Streams', function () {
it('should close the listeners after the cursor is closed', {
metadata: { requires: { topology: 'replicaset' } },
async test() {
const collection = db.collection('closesListeners');
const changeStream = collection.watch(pipeline);
const willBeChanges = on(changeStream, 'change');
await once(changeStream.cursor, 'init');
await collection.insertOne({ a: 1 });

await willBeChanges.next();
expect(changeStream.cursorStream.listenerCount('data')).to.equal(1);
expect(changeStream.cursorStream?.listenerCount('data')).to.equal(1);

await changeStream.close();
expect(changeStream.cursorStream).to.not.exist;
Expand Down Expand Up @@ -1646,7 +1648,7 @@ describe('Change Streams', function () {
it('does not convert Longs to numbers', {
metadata: { requires: { topology: '!single' } },
test: async function () {
cs = collection.watch([], { promoteLongs: true });
cs = collection.watch([], { promoteLongs: true, useBigInt64: false });

const willBeChange = once(cs, 'change').then(args => args[0]);
await once(cs.cursor, 'init');
Expand All @@ -1665,7 +1667,7 @@ describe('Change Streams', function () {
it('converts Long values to native numbers', {
metadata: { requires: { topology: '!single' } },
test: async function () {
cs = collection.watch([], { promoteLongs: false });
cs = collection.watch([], { promoteLongs: false, useBigInt64: false });

const willBeChange = once(cs, 'change').then(args => args[0]);
await once(cs.cursor, 'init');
Expand All @@ -1683,7 +1685,7 @@ describe('Change Streams', function () {
it('defaults to true', {
metadata: { requires: { topology: '!single' } },
test: async function () {
cs = collection.watch([]);
cs = collection.watch([], { useBigInt64: false });

const willBeChange = once(cs, 'change').then(args => args[0]);
await once(cs.cursor, 'init');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ describe('Client Side Encryption Prose Corpus Test', function () {

const corpusDir = path.resolve(__dirname, '../../spec/client-side-encryption/corpus');
function loadCorpusData(filename) {
return EJSON.parse(fs.readFileSync(path.resolve(corpusDir, filename)), { relaxed: false });
return EJSON.parse(fs.readFileSync(path.resolve(corpusDir, filename)), {
relaxed: false
});
}

const CSFLE_KMS_PROVIDERS = process.env.CSFLE_KMS_PROVIDERS;
Expand Down
Loading