mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 09:32:32 +01:00
SERVER-776 NumberLong in sm
This commit is contained in:
parent
155e38b679
commit
bf36eebd4f
@ -541,7 +541,7 @@ namespace JSTests {
|
|||||||
ASSERT( s->exec( "c = {c:a.a.toString()}", "foo", false, true, false ) );
|
ASSERT( s->exec( "c = {c:a.a.toString()}", "foo", false, true, false ) );
|
||||||
out = s->getObject( "c" );
|
out = s->getObject( "c" );
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
ss << val;
|
ss << "NumberLong( \"" << val << "\" )";
|
||||||
ASSERT_EQUALS( ss.str(), out.firstElement().valuestr() );
|
ASSERT_EQUALS( ss.str(), out.firstElement().valuestr() );
|
||||||
|
|
||||||
ASSERT( s->exec( "d = {d:a.a.toNumber()}", "foo", false, true, false ) );
|
ASSERT( s->exec( "d = {d:a.a.toNumber()}", "foo", false, true, false ) );
|
||||||
|
46
jstests/numberlong.js
Normal file
46
jstests/numberlong.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
n = new NumberLong( 4 );
|
||||||
|
assert.eq.automsg( "4", "n" );
|
||||||
|
assert.eq.automsg( "4", "n.toNumber()" );
|
||||||
|
assert.eq.automsg( "8", "n + 4" );
|
||||||
|
assert.eq.automsg( "'NumberLong( 4 )'", "n.toString()" );
|
||||||
|
assert.eq.automsg( "'NumberLong( 4 )'", "tojson( n )" );
|
||||||
|
a = {}
|
||||||
|
a.a = n;
|
||||||
|
p = tojson( a );
|
||||||
|
assert.eq.automsg( "'{ \"a\" : NumberLong( 4 ) }'", "p" );
|
||||||
|
|
||||||
|
n = new NumberLong( -4 );
|
||||||
|
assert.eq.automsg( "-4", "n" );
|
||||||
|
assert.eq.automsg( "-4", "n.toNumber()" );
|
||||||
|
assert.eq.automsg( "0", "n + 4" );
|
||||||
|
assert.eq.automsg( "'NumberLong( -4 )'", "n.toString()" );
|
||||||
|
assert.eq.automsg( "'NumberLong( -4 )'", "tojson( n )" );
|
||||||
|
a = {}
|
||||||
|
a.a = n;
|
||||||
|
p = tojson( a );
|
||||||
|
assert.eq.automsg( "'{ \"a\" : NumberLong( -4 ) }'", "p" );
|
||||||
|
|
||||||
|
// too big to fit in double
|
||||||
|
n = new NumberLong( "11111111111111111" );
|
||||||
|
assert.eq.automsg( "11111111111111112", "n.toNumber()" );
|
||||||
|
assert.eq.automsg( "11111111111111116", "n + 4" );
|
||||||
|
assert.eq.automsg( "'NumberLong( \"11111111111111111\" )'", "n.toString()" );
|
||||||
|
assert.eq.automsg( "'NumberLong( \"11111111111111111\" )'", "tojson( n )" );
|
||||||
|
a = {}
|
||||||
|
a.a = n;
|
||||||
|
p = tojson( a );
|
||||||
|
assert.eq.automsg( "'{ \"a\" : NumberLong( \"11111111111111111\" ) }'", "p" );
|
||||||
|
|
||||||
|
n = new NumberLong( "-11111111111111111" );
|
||||||
|
assert.eq.automsg( "-11111111111111112", "n.toNumber()" );
|
||||||
|
assert.eq.automsg( "-11111111111111108", "n + 4" );
|
||||||
|
assert.eq.automsg( "'NumberLong( \"-11111111111111111\" )'", "n.toString()" );
|
||||||
|
assert.eq.automsg( "'NumberLong( \"-11111111111111111\" )'", "tojson( n )" );
|
||||||
|
a = {}
|
||||||
|
a.a = n;
|
||||||
|
p = tojson( a );
|
||||||
|
assert.eq.automsg( "'{ \"a\" : NumberLong( \"-11111111111111111\" ) }'", "p" );
|
||||||
|
|
||||||
|
// parsing
|
||||||
|
assert.throws.automsg( function() { new NumberLong( "y" ); } );
|
||||||
|
assert.throws.automsg( function() { new NumberLong( "11111111111111111111" ); } );
|
@ -452,6 +452,7 @@
|
|||||||
937D14AB0F2A225F0071FFA9 /* nonce.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nonce.h; sourceTree = "<group>"; };
|
937D14AB0F2A225F0071FFA9 /* nonce.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nonce.h; sourceTree = "<group>"; };
|
||||||
937D14AC0F2A226E0071FFA9 /* nonce.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = nonce.cpp; sourceTree = "<group>"; };
|
937D14AC0F2A226E0071FFA9 /* nonce.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = nonce.cpp; sourceTree = "<group>"; };
|
||||||
938A748A11D140EC005265E1 /* in4.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = in4.js; sourceTree = "<group>"; };
|
938A748A11D140EC005265E1 /* in4.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = in4.js; sourceTree = "<group>"; };
|
||||||
|
938A74BF11D17ECE005265E1 /* numberlong.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = numberlong.js; sourceTree = "<group>"; };
|
||||||
938A7A420F54871000FB7A07 /* storage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = storage.cpp; sourceTree = "<group>"; };
|
938A7A420F54871000FB7A07 /* storage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = storage.cpp; sourceTree = "<group>"; };
|
||||||
938A7A430F54873600FB7A07 /* concurrency.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = concurrency.h; sourceTree = "<group>"; };
|
938A7A430F54873600FB7A07 /* concurrency.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = concurrency.h; sourceTree = "<group>"; };
|
||||||
938A7A440F54873600FB7A07 /* queryutil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = queryutil.cpp; sourceTree = "<group>"; };
|
938A7A440F54873600FB7A07 /* queryutil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = queryutil.cpp; sourceTree = "<group>"; };
|
||||||
@ -822,6 +823,7 @@
|
|||||||
934BEB9A10DFFA9600178102 /* jstests */ = {
|
934BEB9A10DFFA9600178102 /* jstests */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
938A74BF11D17ECE005265E1 /* numberlong.js */,
|
||||||
938A748A11D140EC005265E1 /* in4.js */,
|
938A748A11D140EC005265E1 /* in4.js */,
|
||||||
93C529C511D047CF00CF42F7 /* repair2.js */,
|
93C529C511D047CF00CF42F7 /* repair2.js */,
|
||||||
937884E811C80B22007E85F5 /* or8.js */,
|
937884E811C80B22007E85F5 /* or8.js */,
|
||||||
|
@ -532,6 +532,24 @@ namespace mongo {
|
|||||||
return OBJECT_TO_JSVAL( o );
|
return OBJECT_TO_JSVAL( o );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void makeLongObj( long long n, JSObject * o ) {
|
||||||
|
boost::uint64_t val = (boost::uint64_t)n;
|
||||||
|
CHECKNEWOBJECT(o,_context,"NumberLong1");
|
||||||
|
setProperty( o , "floatApprox" , toval( (double)(boost::int64_t)( val ) ) );
|
||||||
|
if ( (boost::int64_t)val != (boost::int64_t)(double)(boost::int64_t)( val ) ) {
|
||||||
|
// using 2 doubles here instead of a single double because certain double
|
||||||
|
// bit patterns represent undefined values and sm might trash them
|
||||||
|
setProperty( o , "top" , toval( (double)(boost::uint32_t)( val >> 32 ) ) );
|
||||||
|
setProperty( o , "bottom" , toval( (double)(boost::uint32_t)( val & 0x00000000ffffffff ) ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jsval toval( long long n ) {
|
||||||
|
JSObject * o = JS_NewObject( _context , &numberlong_class , 0 , 0 );
|
||||||
|
makeLongObj( n, o );
|
||||||
|
return OBJECT_TO_JSVAL( o );
|
||||||
|
}
|
||||||
|
|
||||||
jsval toval( const BSONElement& e ){
|
jsval toval( const BSONElement& e ){
|
||||||
|
|
||||||
switch( e.type() ){
|
switch( e.type() ){
|
||||||
@ -633,17 +651,7 @@ namespace mongo {
|
|||||||
return OBJECT_TO_JSVAL( o );
|
return OBJECT_TO_JSVAL( o );
|
||||||
}
|
}
|
||||||
case NumberLong: {
|
case NumberLong: {
|
||||||
boost::uint64_t val = (boost::uint64_t)e.numberLong();
|
return toval( e.numberLong() );
|
||||||
JSObject * o = JS_NewObject( _context , &numberlong_class , 0 , 0 );
|
|
||||||
CHECKNEWOBJECT(o,_context,"NumberLong1");
|
|
||||||
setProperty( o , "floatApprox" , toval( (double)(boost::int64_t)( val ) ) );
|
|
||||||
if ( (boost::int64_t)val != (boost::int64_t)(double)(boost::int64_t)( val ) ) {
|
|
||||||
// using 2 doubles here instead of a single double because certain double
|
|
||||||
// bit patterns represent undefined values and sm might trash them
|
|
||||||
setProperty( o , "top" , toval( (double)(boost::uint32_t)( val >> 32 ) ) );
|
|
||||||
setProperty( o , "bottom" , toval( (double)(boost::uint32_t)( val & 0x00000000ffffffff ) ) );
|
|
||||||
}
|
|
||||||
return OBJECT_TO_JSVAL( o );
|
|
||||||
}
|
}
|
||||||
case DBRef: {
|
case DBRef: {
|
||||||
JSObject * o = JS_NewObject( _context , &dbpointer_class , 0 , 0 );
|
JSObject * o = JS_NewObject( _context , &dbpointer_class , 0 , 0 );
|
||||||
@ -664,8 +672,8 @@ namespace mongo {
|
|||||||
const char * data = e.binData( len );
|
const char * data = e.binData( len );
|
||||||
assert( JS_SetPrivate( _context , o , new BinDataHolder( data ) ) );
|
assert( JS_SetPrivate( _context , o , new BinDataHolder( data ) ) );
|
||||||
|
|
||||||
setProperty( o , "len" , toval( len ) );
|
setProperty( o , "len" , toval( (double)len ) );
|
||||||
setProperty( o , "type" , toval( (int)e.binDataType() ) );
|
setProperty( o , "type" , toval( (double)e.binDataType() ) );
|
||||||
return OBJECT_TO_JSVAL( o );
|
return OBJECT_TO_JSVAL( o );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -593,8 +593,8 @@ namespace mongo {
|
|||||||
string decoded = base64::decode( encoded );
|
string decoded = base64::decode( encoded );
|
||||||
|
|
||||||
assert( JS_SetPrivate( cx, obj, new BinDataHolder( decoded.data(), decoded.length() ) ) );
|
assert( JS_SetPrivate( cx, obj, new BinDataHolder( decoded.data(), decoded.length() ) ) );
|
||||||
c.setProperty( obj, "len", c.toval( decoded.length() ) );
|
c.setProperty( obj, "len", c.toval( (double)decoded.length() ) );
|
||||||
c.setProperty( obj, "type", c.toval( type ) );
|
c.setProperty( obj, "type", c.toval( (double)type ) );
|
||||||
|
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
@ -699,6 +699,27 @@ namespace mongo {
|
|||||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
JSBool numberlong_constructor( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval ){
|
||||||
|
smuassert( cx , "NumberLong needs 0 or 1 args" , argc == 0 || argc == 1 );
|
||||||
|
|
||||||
|
Convertor c( cx );
|
||||||
|
if ( argc == 0 ) {
|
||||||
|
c.setProperty( obj, "floatApprox", c.toval( 0.0 ) );
|
||||||
|
} else if ( JSVAL_IS_NUMBER( argv[ 0 ] ) ) {
|
||||||
|
c.setProperty( obj, "floatApprox", argv[ 0 ] );
|
||||||
|
} else {
|
||||||
|
string num = c.toString( argv[ 0 ] );
|
||||||
|
const char *numStr = num.c_str();
|
||||||
|
char *endPtr = 0;
|
||||||
|
errno = 0;
|
||||||
|
long long n = strtoll( numStr, &endPtr, 10 );
|
||||||
|
smuassert( cx , "could not convert numeric representation of string to long" , *endPtr == 0 && errno != ERANGE );
|
||||||
|
c.makeLongObj( n, obj );
|
||||||
|
}
|
||||||
|
|
||||||
|
return JS_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
JSBool numberlong_valueof(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){
|
JSBool numberlong_valueof(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){
|
||||||
Convertor c(cx);
|
Convertor c(cx);
|
||||||
return *rval = c.toval( double( c.toNumberLongUnsafe( obj ) ) );
|
return *rval = c.toval( double( c.toNumberLongUnsafe( obj ) ) );
|
||||||
@ -711,7 +732,12 @@ namespace mongo {
|
|||||||
JSBool numberlong_tostring(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){
|
JSBool numberlong_tostring(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){
|
||||||
Convertor c(cx);
|
Convertor c(cx);
|
||||||
stringstream ss;
|
stringstream ss;
|
||||||
ss << c.toNumberLongUnsafe( obj );
|
long long val = c.toNumberLongUnsafe( obj );
|
||||||
|
if ( val == (long long)(double)( val ) ) {
|
||||||
|
ss << "NumberLong( " << double( val ) << " )";
|
||||||
|
} else {
|
||||||
|
ss << "NumberLong( \"" << val << "\" )";
|
||||||
|
}
|
||||||
string ret = ss.str();
|
string ret = ss.str();
|
||||||
return *rval = c.toval( ret.c_str() );
|
return *rval = c.toval( ret.c_str() );
|
||||||
}
|
}
|
||||||
@ -821,7 +847,7 @@ namespace mongo {
|
|||||||
assert( JS_InitClass( cx , global , 0 , &bindata_class , bindata_constructor , 0 , 0 , bindata_functions , 0 , 0 ) );
|
assert( JS_InitClass( cx , global , 0 , &bindata_class , bindata_constructor , 0 , 0 , bindata_functions , 0 , 0 ) );
|
||||||
|
|
||||||
assert( JS_InitClass( cx , global , 0 , ×tamp_class , 0 , 0 , 0 , 0 , 0 , 0 ) );
|
assert( JS_InitClass( cx , global , 0 , ×tamp_class , 0 , 0 , 0 , 0 , 0 , 0 ) );
|
||||||
assert( JS_InitClass( cx , global , 0 , &numberlong_class , 0 , 0 , 0 , numberlong_functions , 0 , 0 ) );
|
assert( JS_InitClass( cx , global , 0 , &numberlong_class , numberlong_constructor , 0 , 0 , numberlong_functions , 0 , 0 ) );
|
||||||
assert( JS_InitClass( cx , global , 0 , &minkey_class , 0 , 0 , 0 , 0 , 0 , 0 ) );
|
assert( JS_InitClass( cx , global , 0 , &minkey_class , 0 , 0 , 0 , 0 , 0 , 0 ) );
|
||||||
assert( JS_InitClass( cx , global , 0 , &maxkey_class , 0 , 0 , 0 , 0 , 0 , 0 ) );
|
assert( JS_InitClass( cx , global , 0 , &maxkey_class , 0 , 0 , 0 , 0 , 0 , 0 ) );
|
||||||
|
|
||||||
|
@ -344,6 +344,14 @@ Object.keySet = function( o ) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ! NumberLong.prototype ) {
|
||||||
|
NumberLong.prototype = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
NumberLong.prototype.tojson = function() {
|
||||||
|
return this.toString();
|
||||||
|
}
|
||||||
|
|
||||||
if ( ! ObjectId.prototype )
|
if ( ! ObjectId.prototype )
|
||||||
ObjectId.prototype = {}
|
ObjectId.prototype = {}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user