From 022393f1a56917173e2d686ef5400711afb5c55c Mon Sep 17 00:00:00 2001 From: LijieZhang1998 Date: Fri, 10 Oct 2025 16:20:10 -0500 Subject: [PATCH 1/3] STREAMS-1895: Add old shell compatibility of NumberLong for JS Engine --- snippets/mongocompat/mongotypes.js | 43 ++++++++++++++++++++++++++++++ snippets/mongocompat/test.js | 10 +++++++ 2 files changed, 53 insertions(+) diff --git a/snippets/mongocompat/mongotypes.js b/snippets/mongocompat/mongotypes.js index 9a659a8..bdaefd4 100644 --- a/snippets/mongocompat/mongotypes.js +++ b/snippets/mongocompat/mongotypes.js @@ -378,10 +378,53 @@ if (!NumberLong.prototype) { NumberLong.prototype = {}; } +NumberLong.prototype.nativeToString = NumberLong.prototype.toString; +NumberLong.prototype.toString = function () { + return `NumberLong(${this.nativeToString()})`; +}; + NumberLong.prototype.tojson = function() { return this.toString(); }; +Object.defineProperty(NumberLong.prototype, 'floatApprox', { + enumerable: false, + configurable: true, + get: function() { + return Number(this.nativeToString()); + } +}); + +Object.defineProperty(NumberLong.prototype, 'top', { + enumerable: false, + configurable: true, + get: function() { + const str = this.nativeToString(); + const bigIntValue = BigInt(str); + const unsigned64 = bigIntValue < 0n + ? bigIntValue + (1n << 64n) + : bigIntValue; + return Number((unsigned64 >> 32n) & 0xFFFFFFFFn); + } +}); + +Object.defineProperty(NumberLong.prototype, 'bottom', { + enumerable: false, + configurable: true, + get: function() { + const str = this.nativeToString(); + const bigIntValue = BigInt(str); + const unsigned64 = bigIntValue < 0n + ? bigIntValue + (1n << 64n) + : bigIntValue; + return Number(unsigned64 & 0xFFFFFFFFn); + } +}); + +NumberLong.prototype.exactValueString = function() { + return this.nativeToString(); +}; + // NumberInt if (!NumberInt.prototype) { NumberInt.prototype = {}; diff --git a/snippets/mongocompat/test.js b/snippets/mongocompat/test.js index 6913ae0..c724b50 100644 --- a/snippets/mongocompat/test.js +++ b/snippets/mongocompat/test.js @@ -1,4 +1,14 @@ load(__dirname + '/index.js'); assert.strictEqual(ObjectId('0123456789abcdef01234567').tojson(), 'ObjectId("0123456789abcdef01234567")'); + assert.strictEqual(BinData(4, 'abcdefgh').toString(), 'BinData(4,"abcdefgh")'); + +assert.strictEqual(NumberLong(1234567890).toString(), 'NumberLong(1234567890)'); +const nl1 = NumberLong(9.223372036854776e+18, 2147483647, 4294967295); +assert.strictEqual(nl1.floatApprox, 9223372036854776000); +assert.strictEqual(nl1.top, 2147483647); +assert.strictEqual(nl1.bottom, 4294967295); +assert.strictEqual(nl1.exactValueString(), "9223372036854775807"); +const nl2 = NumberLong("200"); +assert.strictEqual(nl1.compare(nl2), 1); From 41ffb3b7dc633b357c14a6e46968f08e02876504 Mon Sep 17 00:00:00 2001 From: LijieZhang1998 Date: Mon, 13 Oct 2025 09:03:20 -0500 Subject: [PATCH 2/3] refactor by comments --- snippets/mongocompat/mongotypes.js | 38 +++++++++++++++++------------- snippets/mongocompat/test.js | 25 ++++++++++++++------ 2 files changed, 39 insertions(+), 24 deletions(-) diff --git a/snippets/mongocompat/mongotypes.js b/snippets/mongocompat/mongotypes.js index bdaefd4..32539d9 100644 --- a/snippets/mongocompat/mongotypes.js +++ b/snippets/mongocompat/mongotypes.js @@ -380,7 +380,14 @@ if (!NumberLong.prototype) { NumberLong.prototype.nativeToString = NumberLong.prototype.toString; NumberLong.prototype.toString = function () { - return `NumberLong(${this.nativeToString()})`; + const INT32_MIN = -2147483648; + const INT32_MAX = 2147483647; + + const numValue = this.toNumber ? this.toNumber() : Number(this); + if (numValue >= INT32_MIN && numValue <= INT32_MAX && Number.isInteger(numValue)) { + return `NumberLong(${numValue})`; + } + return `NumberLong("${this.exactValueString}")`; }; NumberLong.prototype.tojson = function() { @@ -391,7 +398,7 @@ Object.defineProperty(NumberLong.prototype, 'floatApprox', { enumerable: false, configurable: true, get: function() { - return Number(this.nativeToString()); + return this.toNumber ? this.toNumber() : Number(this); } }); @@ -399,12 +406,7 @@ Object.defineProperty(NumberLong.prototype, 'top', { enumerable: false, configurable: true, get: function() { - const str = this.nativeToString(); - const bigIntValue = BigInt(str); - const unsigned64 = bigIntValue < 0n - ? bigIntValue + (1n << 64n) - : bigIntValue; - return Number((unsigned64 >> 32n) & 0xFFFFFFFFn); + return this.high; } }); @@ -412,18 +414,20 @@ Object.defineProperty(NumberLong.prototype, 'bottom', { enumerable: false, configurable: true, get: function() { - const str = this.nativeToString(); - const bigIntValue = BigInt(str); - const unsigned64 = bigIntValue < 0n - ? bigIntValue + (1n << 64n) - : bigIntValue; - return Number(unsigned64 & 0xFFFFFFFFn); + return this.low; } }); -NumberLong.prototype.exactValueString = function() { - return this.nativeToString(); -}; +Object.defineProperty(NumberLong.prototype, 'exactValueString', { + enumerable: false, + configurable: true, + get: function() { + const high = BigInt(this.high); + const low = BigInt(this.low >>> 0); + const value = (high << 32n) | low; + return value.toString(); + } +}); // NumberInt if (!NumberInt.prototype) { diff --git a/snippets/mongocompat/test.js b/snippets/mongocompat/test.js index c724b50..3dd110b 100644 --- a/snippets/mongocompat/test.js +++ b/snippets/mongocompat/test.js @@ -4,11 +4,22 @@ assert.strictEqual(ObjectId('0123456789abcdef01234567').tojson(), 'ObjectId("012 assert.strictEqual(BinData(4, 'abcdefgh').toString(), 'BinData(4,"abcdefgh")'); -assert.strictEqual(NumberLong(1234567890).toString(), 'NumberLong(1234567890)'); -const nl1 = NumberLong(9.223372036854776e+18, 2147483647, 4294967295); -assert.strictEqual(nl1.floatApprox, 9223372036854776000); -assert.strictEqual(nl1.top, 2147483647); -assert.strictEqual(nl1.bottom, 4294967295); -assert.strictEqual(nl1.exactValueString(), "9223372036854775807"); +assert.strictEqual(NumberLong(2147483647).toString(), 'NumberLong(2147483647)'); +assert.strictEqual(NumberLong("2147483648").toString(), 'NumberLong("2147483648")'); +assert.strictEqual(NumberLong(-2147483648).toString(), 'NumberLong(-2147483648)'); +console.log(NumberLong(-2147483649).toString()); +assert.strictEqual(NumberLong(-2147483649).toString(), 'NumberLong("-2147483649")'); +assert.strictEqual(NumberLong(9223372036854775807).toString(), 'NumberLong("9223372036854775807")'); +assert.strictEqual(NumberLong(-9223372036854775808).toString(), 'NumberLong("-9223372036854775808")'); +const maxLong = NumberLong(9223372036854775807, 2147483647, -1); +assert.strictEqual(maxLong.floatApprox, 9223372036854775807); +assert.strictEqual(maxLong.top, 2147483647); +assert.strictEqual(maxLong.bottom, -1);//mongosh uses signed representation, while old shell uses unsigned +assert.strictEqual(maxLong.exactValueString, "9223372036854775807"); +const minLong = NumberLong(-9223372036854775808); +assert.strictEqual(minLong.floatApprox, -9223372036854776000); +assert.strictEqual(minLong.top, -2147483648); +assert.strictEqual(minLong.bottom, 0); +assert.strictEqual(minLong.exactValueString, "-9223372036854775808"); const nl2 = NumberLong("200"); -assert.strictEqual(nl1.compare(nl2), 1); +assert.strictEqual(maxLong.compare(nl2), 1); From 7b5ad9477ba6970bbbdb00b526fd4bc540a6579b Mon Sep 17 00:00:00 2001 From: LijieZhang1998 Date: Mon, 13 Oct 2025 09:09:02 -0500 Subject: [PATCH 3/3] remove debug --- snippets/mongocompat/test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/snippets/mongocompat/test.js b/snippets/mongocompat/test.js index 3dd110b..66e15f7 100644 --- a/snippets/mongocompat/test.js +++ b/snippets/mongocompat/test.js @@ -7,7 +7,6 @@ assert.strictEqual(BinData(4, 'abcdefgh').toString(), 'BinData(4,"abcdefgh")'); assert.strictEqual(NumberLong(2147483647).toString(), 'NumberLong(2147483647)'); assert.strictEqual(NumberLong("2147483648").toString(), 'NumberLong("2147483648")'); assert.strictEqual(NumberLong(-2147483648).toString(), 'NumberLong(-2147483648)'); -console.log(NumberLong(-2147483649).toString()); assert.strictEqual(NumberLong(-2147483649).toString(), 'NumberLong("-2147483649")'); assert.strictEqual(NumberLong(9223372036854775807).toString(), 'NumberLong("9223372036854775807")'); assert.strictEqual(NumberLong(-9223372036854775808).toString(), 'NumberLong("-9223372036854775808")');