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 ) );
|
||||
out = s->getObject( "c" );
|
||||
stringstream ss;
|
||||
ss << val;
|
||||
ss << "NumberLong( \"" << val << "\" )";
|
||||
ASSERT_EQUALS( ss.str(), out.firstElement().valuestr() );
|
||||
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
@ -822,6 +823,7 @@
|
||||
934BEB9A10DFFA9600178102 /* jstests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
938A74BF11D17ECE005265E1 /* numberlong.js */,
|
||||
938A748A11D140EC005265E1 /* in4.js */,
|
||||
93C529C511D047CF00CF42F7 /* repair2.js */,
|
||||
937884E811C80B22007E85F5 /* or8.js */,
|
||||
|
@ -532,6 +532,24 @@ namespace mongo {
|
||||
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 ){
|
||||
|
||||
switch( e.type() ){
|
||||
@ -633,17 +651,7 @@ namespace mongo {
|
||||
return OBJECT_TO_JSVAL( o );
|
||||
}
|
||||
case NumberLong: {
|
||||
boost::uint64_t val = (boost::uint64_t)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 );
|
||||
return toval( e.numberLong() );
|
||||
}
|
||||
case DBRef: {
|
||||
JSObject * o = JS_NewObject( _context , &dbpointer_class , 0 , 0 );
|
||||
@ -664,8 +672,8 @@ namespace mongo {
|
||||
const char * data = e.binData( len );
|
||||
assert( JS_SetPrivate( _context , o , new BinDataHolder( data ) ) );
|
||||
|
||||
setProperty( o , "len" , toval( len ) );
|
||||
setProperty( o , "type" , toval( (int)e.binDataType() ) );
|
||||
setProperty( o , "len" , toval( (double)len ) );
|
||||
setProperty( o , "type" , toval( (double)e.binDataType() ) );
|
||||
return OBJECT_TO_JSVAL( o );
|
||||
}
|
||||
}
|
||||
|
@ -593,8 +593,8 @@ namespace mongo {
|
||||
string decoded = base64::decode( encoded );
|
||||
|
||||
assert( JS_SetPrivate( cx, obj, new BinDataHolder( decoded.data(), decoded.length() ) ) );
|
||||
c.setProperty( obj, "len", c.toval( decoded.length() ) );
|
||||
c.setProperty( obj, "type", c.toval( type ) );
|
||||
c.setProperty( obj, "len", c.toval( (double)decoded.length() ) );
|
||||
c.setProperty( obj, "type", c.toval( (double)type ) );
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
@ -699,6 +699,27 @@ namespace mongo {
|
||||
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){
|
||||
Convertor c(cx);
|
||||
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){
|
||||
Convertor c(cx);
|
||||
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();
|
||||
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 , ×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 , &maxkey_class , 0 , 0 , 0 , 0 , 0 , 0 ) );
|
||||
|
||||
|
@ -15,15 +15,15 @@ friendlyEqual = function( a , b ){
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
doassert = function (msg) {
|
||||
if (msg.indexOf("assert") == 0)
|
||||
print(msg);
|
||||
else
|
||||
print("assert: " + msg);
|
||||
throw msg;
|
||||
}
|
||||
|
||||
|
||||
doassert = function (msg) {
|
||||
if (msg.indexOf("assert") == 0)
|
||||
print(msg);
|
||||
else
|
||||
print("assert: " + msg);
|
||||
throw msg;
|
||||
}
|
||||
|
||||
assert = function( b , msg ){
|
||||
@ -344,6 +344,14 @@ Object.keySet = function( o ) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ( ! NumberLong.prototype ) {
|
||||
NumberLong.prototype = {}
|
||||
}
|
||||
|
||||
NumberLong.prototype.tojson = function() {
|
||||
return this.toString();
|
||||
}
|
||||
|
||||
if ( ! ObjectId.prototype )
|
||||
ObjectId.prototype = {}
|
||||
|
||||
@ -816,10 +824,10 @@ shellHelper = function( command , rest , shouldPrint ){
|
||||
help = shellHelper.help = function (x) {
|
||||
if (x == "admin") {
|
||||
print("\tls([path]) list files");
|
||||
print("\tpwd() returns current directory");
|
||||
print("\tlistFiles([path]) returns file list");
|
||||
print("\thostname() returns name of this host");
|
||||
print("\tcat(fname) returns contents of text file as a string");
|
||||
print("\tpwd() returns current directory");
|
||||
print("\tlistFiles([path]) returns file list");
|
||||
print("\thostname() returns name of this host");
|
||||
print("\tcat(fname) returns contents of text file as a string");
|
||||
print("\tremoveFile(f) delete a file");
|
||||
print("\tload(jsfilename) load and execute a .js file");
|
||||
print("\trun(program[, args...]) spawn a program and wait for its completion");
|
||||
|
Loading…
Reference in New Issue
Block a user