Skip to content

Commit 4ae06cf

Browse files
STREAMS-1895: Add old shell compatibility of NumberLong for JS Engine (#16)
1 parent ceb23b8 commit 4ae06cf

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-0
lines changed

snippets/mongocompat/mongotypes.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,10 +378,57 @@ if (!NumberLong.prototype) {
378378
NumberLong.prototype = {};
379379
}
380380

381+
NumberLong.prototype.nativeToString = NumberLong.prototype.toString;
382+
NumberLong.prototype.toString = function () {
383+
const INT32_MIN = -2147483648;
384+
const INT32_MAX = 2147483647;
385+
386+
const numValue = this.toNumber ? this.toNumber() : Number(this);
387+
if (numValue >= INT32_MIN && numValue <= INT32_MAX && Number.isInteger(numValue)) {
388+
return `NumberLong(${numValue})`;
389+
}
390+
return `NumberLong("${this.exactValueString}")`;
391+
};
392+
381393
NumberLong.prototype.tojson = function() {
382394
return this.toString();
383395
};
384396

397+
Object.defineProperty(NumberLong.prototype, 'floatApprox', {
398+
enumerable: false,
399+
configurable: true,
400+
get: function() {
401+
return this.toNumber ? this.toNumber() : Number(this);
402+
}
403+
});
404+
405+
Object.defineProperty(NumberLong.prototype, 'top', {
406+
enumerable: false,
407+
configurable: true,
408+
get: function() {
409+
return this.high;
410+
}
411+
});
412+
413+
Object.defineProperty(NumberLong.prototype, 'bottom', {
414+
enumerable: false,
415+
configurable: true,
416+
get: function() {
417+
return this.low;
418+
}
419+
});
420+
421+
Object.defineProperty(NumberLong.prototype, 'exactValueString', {
422+
enumerable: false,
423+
configurable: true,
424+
get: function() {
425+
const high = BigInt(this.high);
426+
const low = BigInt(this.low >>> 0);
427+
const value = (high << 32n) | low;
428+
return value.toString();
429+
}
430+
});
431+
385432
// NumberInt
386433
if (!NumberInt.prototype) {
387434
NumberInt.prototype = {};

snippets/mongocompat/test.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,24 @@
11
load(__dirname + '/index.js');
22

33
assert.strictEqual(ObjectId('0123456789abcdef01234567').tojson(), 'ObjectId("0123456789abcdef01234567")');
4+
45
assert.strictEqual(BinData(4, 'abcdefgh').toString(), 'BinData(4,"abcdefgh")');
6+
7+
assert.strictEqual(NumberLong(2147483647).toString(), 'NumberLong(2147483647)');
8+
assert.strictEqual(NumberLong("2147483648").toString(), 'NumberLong("2147483648")');
9+
assert.strictEqual(NumberLong(-2147483648).toString(), 'NumberLong(-2147483648)');
10+
assert.strictEqual(NumberLong(-2147483649).toString(), 'NumberLong("-2147483649")');
11+
assert.strictEqual(NumberLong(9223372036854775807).toString(), 'NumberLong("9223372036854775807")');
12+
assert.strictEqual(NumberLong(-9223372036854775808).toString(), 'NumberLong("-9223372036854775808")');
13+
const maxLong = NumberLong(9223372036854775807, 2147483647, -1);
14+
assert.strictEqual(maxLong.floatApprox, 9223372036854775807);
15+
assert.strictEqual(maxLong.top, 2147483647);
16+
assert.strictEqual(maxLong.bottom, -1);//mongosh uses signed representation, while old shell uses unsigned
17+
assert.strictEqual(maxLong.exactValueString, "9223372036854775807");
18+
const minLong = NumberLong(-9223372036854775808);
19+
assert.strictEqual(minLong.floatApprox, -9223372036854776000);
20+
assert.strictEqual(minLong.top, -2147483648);
21+
assert.strictEqual(minLong.bottom, 0);
22+
assert.strictEqual(minLong.exactValueString, "-9223372036854775808");
23+
const nl2 = NumberLong("200");
24+
assert.strictEqual(maxLong.compare(nl2), 1);

0 commit comments

Comments
 (0)