Skip to content

Commit 6c804fa

Browse files
committed
feat: reverse and extend Timestamp constructor arguments MONGOSH-930
- Accept a `Timestamp({ t: <number>, i: <number> })` signature - Reverse the order of arguments when two arguments are passed, i.e. `Timestamp(t, i)` instead of `Timestamp(i, t)`, to match the legacy shell - Print Timestamps using the `Timestamp({ t, i })` format This should land together with the corresponding BSON package PR, mongodb/js-bson#449.
1 parent fb16917 commit 6c804fa

File tree

6 files changed

+33
-15
lines changed

6 files changed

+33
-15
lines changed

packages/cli-repl/test/e2e-bson.spec.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ describe('BSON e2e', function() {
4444
MaxKey: 'MaxKey()',
4545
NumberInt: 'Int32(32)',
4646
NumberLong: 'Long("64")',
47-
Timestamp: 'Timestamp(1, 100)',
47+
Timestamp: 'Timestamp({ t: 100, i: 1 })',
4848
Symbol: 'abc',
4949
Code: 'Code("abc")',
5050
NumberDecimal: 'Decimal128("1")',
@@ -61,7 +61,7 @@ describe('BSON e2e', function() {
6161
DBRef3: new bson.DBRef('a', { x: '5f16b8bebe434dc98cdfc9cb' } as any, 'db'),
6262
MinKey: new bson.MinKey(),
6363
MaxKey: new bson.MaxKey(),
64-
Timestamp: new bson.Timestamp(1, 100),
64+
Timestamp: new bson.Timestamp(new bson.Long(1, 100)),
6565
Symbol: new bson.BSONSymbol('abc'),
6666
Code: new bson.Code('abc'),
6767
NumberDecimal: new bson.Decimal128('1'),
@@ -97,7 +97,7 @@ describe('BSON e2e', function() {
9797
MaxKey: new MaxKey(),
9898
NumberInt: NumberInt("32"),
9999
NumberLong: NumberLong("64"),
100-
Timestamp: new Timestamp(1, 100),
100+
Timestamp: new Timestamp(100, 1),
101101
Symbol: new BSONSymbol('abc'),
102102
Code: new Code('abc'),
103103
NumberDecimal: NumberDecimal('1'),
@@ -164,10 +164,10 @@ describe('BSON e2e', function() {
164164
shell.assertNoErrors();
165165
});
166166
it('Timestamp prints when returned from the server', async() => {
167-
const value = new bson.Timestamp(0, 100);
167+
const value = new bson.Timestamp(new bson.Long(0, 100));
168168
await shell.executeLine(`use ${dbName}`);
169169
await db.collection('test').insertOne({ value: value });
170-
expect(await shell.executeLine('db.test.findOne().value')).to.include('Timestamp(0, 100)');
170+
expect(await shell.executeLine('db.test.findOne().value')).to.include('Timestamp({ t: 100, i: 0 })');
171171
shell.assertNoErrors();
172172
});
173173
it('Code prints when returned from the server', async() => {
@@ -249,8 +249,13 @@ describe('BSON e2e', function() {
249249
expect(await shell.executeLine(value)).to.include('Long("345678654321234561")');
250250
shell.assertNoErrors();
251251
});
252-
it('Timestamp prints when created by user', async() => {
253-
const value = 'Timestamp(0, 100)';
252+
it('Timestamp prints when created by user (legacy)', async() => {
253+
const value = 'Timestamp(100, 0)';
254+
expect(await shell.executeLine(value)).to.include('Timestamp({ t: 100, i: 0 })');
255+
shell.assertNoErrors();
256+
});
257+
it('Timestamp prints when created by user ({t, i})', async() => {
258+
const value = 'Timestamp({ t: 100, i: 0 })';
254259
expect(await shell.executeLine(value)).to.include(value);
255260
shell.assertNoErrors();
256261
});

packages/service-provider-core/src/printable-bson.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ describe('BSON printers', function() {
4444
});
4545

4646
it('formats Timestamp correctly', function() {
47-
expect(inspect(new bson.Timestamp(1, 100))).to.equal('Timestamp(1, 100)');
47+
expect(inspect(new bson.Timestamp(new bson.Long(100, 1)))).to.equal('Timestamp({ t: 1, i: 100 })');
4848
});
4949

5050
it('formats Symbol correctly', function() {

packages/service-provider-core/src/printable-bson.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export const bsonStringifiers: Record<string, (this: any, depth: any, options: a
2323
},
2424

2525
Timestamp: function(): string {
26-
return `Timestamp(${this.getLowBits().toString()}, ${this.getHighBits().toString()})`;
26+
return `Timestamp({ t: ${this.getHighBits()}, i: ${this.getLowBits()} })`;
2727
},
2828

2929
BSONSymbol: function(): string {

packages/shell-api/src/shard.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1293,7 +1293,7 @@ describe('Shard', () => {
12931293
// Make sure that each individual chunk in the output is on a single line
12941294
expect(inspectedCollectionInfo).to.include('chunks: [\n' +
12951295
' { min: { key: MinKey() }, max: { key: MaxKey() }, ' +
1296-
`'on shard': '${collectionInfo.chunks[0]['on shard']}', 'last modified': Timestamp(0, 1) }\n` +
1296+
`'on shard': '${collectionInfo.chunks[0]['on shard']}', 'last modified': Timestamp({ t: 1, i: 0 }) }\n` +
12971297
' ],\n');
12981298
});
12991299
});

packages/shell-api/src/shell-bson.spec.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,14 @@ describe('Shell BSON', () => {
196196
});
197197
it('constructs with default args 1', () => {
198198
const s = shellBson.Timestamp(1);
199-
expect(s.low).to.equal(1);
200-
expect(s.high).to.equal(0);
199+
expect(s.low).to.equal(0);
200+
expect(s.high).to.equal(1);
201+
});
202+
it('constructs with { t, i } signature', () => {
203+
const s = shellBson.Timestamp({ t: 10, i: 20 });
204+
expect(s.low).to.equal(20);
205+
expect(s.high).to.equal(10);
206+
expect(s.toExtendedJSON()).to.deep.equal({ $timestamp: { t: 10, i: 20 } });
201207
});
202208
});
203209
describe('Code', () => {

packages/shell-api/src/shell-bson.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,16 @@ export default function constructShellBson(bson: typeof BSON, printWarning: (msg
7171
assertArgsDefinedType([id], [[undefined, 'string', 'number', 'object']], 'ObjectId');
7272
return new bson.ObjectId(id);
7373
}, { ...bson.ObjectId, prototype: bson.ObjectId.prototype }),
74-
Timestamp: Object.assign(function Timestamp(low?: number | typeof bson.Long.prototype, high?: number): typeof bson.Timestamp.prototype {
75-
assertArgsDefinedType([low, high], [['number', 'object', undefined], [undefined, 'number']], 'Timestamp');
76-
return new bson.Timestamp(low as number, high as number);
74+
Timestamp: Object.assign(function Timestamp(t?: number | typeof bson.Long.prototype | { t: number, i: number }, i?: number): typeof bson.Timestamp.prototype {
75+
assertArgsDefinedType([t, i], [['number', 'object', undefined], [undefined, 'number']], 'Timestamp');
76+
// Order of Timestamp() arguments is reversed in mongo/mongosh and the driver:
77+
// https://jira.mongodb.org/browse/MONGOSH-930
78+
if (typeof t === 'object' && t !== null && 't' in t && 'i' in t) {
79+
return new bson.Timestamp(new bson.Long(t.i, t.t));
80+
} else if (i !== undefined || typeof t === 'number') {
81+
return new bson.Timestamp(new bson.Long((i ?? 0) as number, t as number));
82+
}
83+
return new bson.Timestamp(t as typeof bson.Long.prototype);
7784
}, { ...bson.Timestamp, prototype: bson.Timestamp.prototype }),
7885
Code: Object.assign(function Code(c: string | Function = '', s?: any): typeof bson.Code.prototype {
7986
assertArgsDefinedType([c, s], [[undefined, 'string', 'function'], [undefined, 'object']], 'Code');

0 commit comments

Comments
 (0)