diff options
author | Eliot Horowitz <eliot@10gen.com> | 2009-05-22 10:48:05 -0400 |
---|---|---|
committer | Eliot Horowitz <eliot@10gen.com> | 2009-05-22 10:48:05 -0400 |
commit | 2eddff58bb98e81a7cb34d193a16354bf1e17eb3 (patch) | |
tree | 035164e46cc80f35ae91a37f97618865afb540f4 | |
parent | a8d140ae7985551b73ea3a2b660f517b1bfc7cc0 (diff) | |
download | mongo-2eddff58bb98e81a7cb34d193a16354bf1e17eb3.tar.gz |
conserver types when doing bson -> js -> bson as much as possible
-rw-r--r-- | dbtests/jstests.cpp | 51 | ||||
-rw-r--r-- | scripting/engine_spidermonkey.cpp | 29 |
2 files changed, 74 insertions, 6 deletions
diff --git a/dbtests/jstests.cpp b/dbtests/jstests.cpp index 300b69a69fd..3e2c6c63a78 100644 --- a/dbtests/jstests.cpp +++ b/dbtests/jstests.cpp @@ -315,7 +315,57 @@ namespace JSTests { delete s; } }; + + class TypeConservation { + public: + void run(){ + Scope * s = globalScriptEngine->createScope(); + + // -- A -- + + BSONObj o; + { + BSONObjBuilder b ; + b.append( "a" , (int)5 ); + b.append( "b" , 5.6 ); + o = b.obj(); + } + ASSERT_EQUALS( NumberInt , o["a"].type() ); + ASSERT_EQUALS( NumberDouble , o["b"].type() ); + + s->setObject( "z" , o ); + s->invoke( "return z" , BSONObj() ); + BSONObj out = s->getObject( "return" ); + ASSERT_EQUALS( 5 , out["a"].number() ); + ASSERT_EQUALS( 5.6 , out["b"].number() ); + ASSERT_EQUALS( NumberDouble , out["b"].type() ); + ASSERT_EQUALS( NumberInt , out["a"].type() ); + + // -- B -- + + { + BSONObjBuilder b ; + b.append( "a" , (int)5 ); + b.append( "b" , 5.6 ); + o = b.obj(); + } + + s->setObject( "z" , o , false ); + s->invoke( "return z" , BSONObj() ); + out = s->getObject( "return" ); + ASSERT_EQUALS( 5 , out["a"].number() ); + ASSERT_EQUALS( 5.6 , out["b"].number() ); + + ASSERT_EQUALS( NumberDouble , out["b"].type() ); + ASSERT_EQUALS( NumberInt , out["a"].type() ); + + + + delete s; + } + + }; class All : public Suite { public: @@ -330,6 +380,7 @@ namespace JSTests { add< ObjectModTests >(); add< OtherJSTypes >(); add< SpecialDBTypes >(); + add< TypeConservation >(); } }; diff --git a/scripting/engine_spidermonkey.cpp b/scripting/engine_spidermonkey.cpp index 06e224a0070..13fd44845f4 100644 --- a/scripting/engine_spidermonkey.cpp +++ b/scripting/engine_spidermonkey.cpp @@ -113,13 +113,22 @@ namespace mongo { if ( ! o ) return BSONObj(); + if ( JS_InstanceOf( _context , o , &bson_ro_class , 0 ) ){ + return GETHOLDER( _context , o )->_obj.getOwned(); + } + + BSONObj orig; + if ( JS_InstanceOf( _context , o , &bson_class , 0 ) ){ + orig = GETHOLDER(_context,o)->_obj; + } + BSONObjBuilder b; jsval theid = getProperty( o , "_id" ); if ( ! JSVAL_IS_VOID( theid ) ){ append( b , "_id" , theid ); } - + JSIdArray * properties = JS_Enumerate( _context , o ); assert( properties ); @@ -130,7 +139,8 @@ namespace mongo { string name = toString( nameval ); if ( name == "_id" ) continue; - append( b , name , getProperty( o , name.c_str() ) ); + + append( b , name , getProperty( o , name.c_str() ) , orig[name].type() ); } return b.obj(); @@ -154,14 +164,21 @@ namespace mongo { return getFunctionCode( JS_ValueToFunction( _context , v ) ); } - void append( BSONObjBuilder& b , string name , jsval val ){ - //cout << "name: " << name << "\t" << typeString( val ) << endl; + void append( BSONObjBuilder& b , string name , jsval val , BSONType oldType = EOO ){ + //cout << "name: " << name << "\t" << typeString( val ) << " oldType: " << oldType << endl; switch ( JS_TypeOfValue( _context , val ) ){ - + case JSTYPE_VOID: b.appendUndefined( name.c_str() ); break; case JSTYPE_NULL: b.appendNull( name.c_str() ); break; - case JSTYPE_NUMBER: b.append( name.c_str() , toNumber( val ) ); break; + case JSTYPE_NUMBER: { + double d = toNumber( val ); + if ( oldType == NumberInt && ((int)d) == d ) + b.append( name.c_str() , (int)d ); + else + b.append( name.c_str() , d ); + break; + } case JSTYPE_STRING: b.append( name.c_str() , toString( val ) ); break; case JSTYPE_BOOLEAN: b.appendBool( name.c_str() , toBoolean( val ) ); break; |