diff options
-rw-r--r-- | dbtests/jstests.cpp | 20 | ||||
-rw-r--r-- | mongo.xcodeproj/project.pbxproj | 6 | ||||
-rw-r--r-- | scripting/engine_spidermonkey.cpp | 5 | ||||
-rw-r--r-- | scripting/sm_db.cpp | 28 |
4 files changed, 42 insertions, 17 deletions
diff --git a/dbtests/jstests.cpp b/dbtests/jstests.cpp index 20b32089c6f..6ab3e0c2b39 100644 --- a/dbtests/jstests.cpp +++ b/dbtests/jstests.cpp @@ -704,6 +704,25 @@ namespace JSTests { const char * _b; }; + class InformalDBRef { + public: + void run() { + client.insert( ns(), BSON( "i" << 1 ) ); + BSONObj obj = client.findOne( ns(), BSONObj() ); + client.remove( ns(), BSONObj() ); + client.insert( ns(), BSON( "r" << BSON( "$ref" << "jstests.informaldbref" << "$id" << obj["_id"].__oid() << "foo" << "bar" ) ) ); + obj = client.findOne( ns(), BSONObj() ); + ASSERT_EQUALS( "bar", obj[ "r" ].embeddedObject()[ "foo" ].str() ); + + ASSERT( client.eval( "unittest", "x = db.jstests.informaldbref.findOne(); y = { r:x.r }; db.jstests.informaldbref.drop(); y.r[ \"a\" ] = \"b\"; db.jstests.informaldbref.save( y );" ) ); + obj = client.findOne( ns(), BSONObj() ); + ASSERT_EQUALS( "bar", obj[ "r" ].embeddedObject()[ "foo" ].str() ); + ASSERT_EQUALS( "b", obj[ "r" ].embeddedObject()[ "a" ].str() ); + } + private: + static const char *ns() { return "unittest.jstests.informaldbref"; } + }; + class BinDataType { public: @@ -807,6 +826,7 @@ namespace JSTests { add< LongUtf8String >(); add< CodeTests >(); add< DBRefTest >(); + add< InformalDBRef >(); add< BinDataType >(); add< VarTests >(); diff --git a/mongo.xcodeproj/project.pbxproj b/mongo.xcodeproj/project.pbxproj index 48005c6dcd1..731b0da6360 100644 --- a/mongo.xcodeproj/project.pbxproj +++ b/mongo.xcodeproj/project.pbxproj @@ -469,6 +469,9 @@ 93B9F76A112B6C020066ECD2 /* snapshot1.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = snapshot1.js; sourceTree = "<group>"; }; 93B9F76B112B6C1D0066ECD2 /* snapshot2.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = snapshot2.js; sourceTree = "<group>"; }; 93B9F7E6112B98710066ECD2 /* snapshot3.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = snapshot3.js; sourceTree = "<group>"; }; + 93B9F91A112C7F200066ECD2 /* set4.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = set4.js; sourceTree = "<group>"; }; + 93B9F91B112C7F200066ECD2 /* set5.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = set5.js; sourceTree = "<group>"; }; + 93B9F91C112C7F200066ECD2 /* set6.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = set6.js; sourceTree = "<group>"; }; 93BC2AE10FB87662006BC285 /* cursortests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cursortests.cpp; sourceTree = "<group>"; }; 93BC2AE20FB87662006BC285 /* jstests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = jstests.cpp; sourceTree = "<group>"; }; 93BCE15610F25DFE00FA139B /* arrayfind1.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = arrayfind1.js; sourceTree = "<group>"; }; @@ -739,6 +742,9 @@ 934BEB9A10DFFA9600178102 /* jstests */ = { isa = PBXGroup; children = ( + 93B9F91A112C7F200066ECD2 /* set4.js */, + 93B9F91B112C7F200066ECD2 /* set5.js */, + 93B9F91C112C7F200066ECD2 /* set6.js */, 93B9F671112B3AD40066ECD2 /* copyauth.js */, 93D5A8921117A1380052C931 /* regex6.js */, 938E639A110FC66900A8760A /* auth */, diff --git a/scripting/engine_spidermonkey.cpp b/scripting/engine_spidermonkey.cpp index 7b7527723bf..294431c6e35 100644 --- a/scripting/engine_spidermonkey.cpp +++ b/scripting/engine_spidermonkey.cpp @@ -453,8 +453,7 @@ namespace mongo { if ( ref == obj->firstElement().fieldName() ){ JSObject * o = JS_NewObject( _context , &dbref_class , NULL, NULL); assert( o ); - setProperty( o , "$ref" , toval( obj->firstElement() ) ); - setProperty( o , "$id" , toval( (*obj)["$id"] ) ); + assert( JS_SetPrivate( _context , o , (void*)(new BSONHolder( obj->getOwned() ) ) ) ); return o; } JSObject * o = JS_NewObject( _context , readOnly ? &bson_ro_class : &bson_class , NULL, NULL); @@ -768,6 +767,8 @@ namespace mongo { JSBool mark_modified( JSContext *cx, JSObject *obj, jsval idval, jsval *vp){ Convertor c(cx); BSONHolder * holder = GETHOLDER( cx , obj ); + if ( !holder ) // needed when we're messing with DBRef.prototype + return JS_TRUE; if ( holder->_inResolve ) return JS_TRUE; holder->_modified = true; diff --git a/scripting/sm_db.cpp b/scripting/sm_db.cpp index d3db026a635..ca4526a3c40 100644 --- a/scripting/sm_db.cpp +++ b/scripting/sm_db.cpp @@ -563,29 +563,24 @@ namespace mongo { JSBool dbref_constructor( JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval ){ Convertor c( cx ); - + if ( argc == 2 ){ - assert( JS_SetProperty( cx , obj , "$ref" , &(argv[0]) ) ); - assert( JS_SetProperty( cx , obj , "$id" , &(argv[1]) ) ); + JSObject * o = JS_NewObject( cx , NULL , NULL, NULL ); + assert( o ); + assert( JS_SetProperty( cx, o , "$ref" , &argv[ 0 ] ) ); + assert( JS_SetProperty( cx, o , "$id" , &argv[ 1 ] ) ); + BSONObj bo = c.toObject( o ); + assert( JS_SetPrivate( cx , obj , (void*)(new BSONHolder( bo.getOwned() ) ) ) ); return JS_TRUE; } else { JS_ReportError( cx , "DBRef needs 2 arguments" ); + assert( JS_SetPrivate( cx , obj , (void*)(new BSONHolder( BSONObj().getOwned() ) ) ) ); return JS_FALSE; } } - JSClass dbref_class = { - "DBRef" , JSCLASS_HAS_PRIVATE , - JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, - JS_EnumerateStub, JS_ResolveStub , JS_ConvertStub, JS_FinalizeStub, - JSCLASS_NO_OPTIONAL_MEMBERS - }; - - JSFunctionSpec dbref_functions[] = { - { 0 } - }; - + JSClass dbref_class = bson_class; // name will be fixed later // BinData @@ -817,7 +812,6 @@ namespace mongo { assert( JS_InitClass( cx , global , 0 , &internal_cursor_class , internal_cursor_constructor , 0 , 0 , internal_cursor_functions , 0 , 0 ) ); assert( JS_InitClass( cx , global , 0 , &dbquery_class , dbquery_constructor , 0 , 0 , 0 , 0 , 0 ) ); assert( JS_InitClass( cx , global , 0 , &dbpointer_class , dbpointer_constructor , 0 , 0 , dbpointer_functions , 0 , 0 ) ); - assert( JS_InitClass( cx , global , 0 , &dbref_class , dbref_constructor , 0 , 0 , dbref_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 ) ); @@ -830,6 +824,10 @@ namespace mongo { assert( JS_InitClass( cx , global , 0 , &bson_ro_class , bson_cons , 0 , 0 , bson_functions , 0 , 0 ) ); assert( JS_InitClass( cx , global , 0 , &bson_class , bson_cons , 0 , 0 , bson_functions , 0 , 0 ) ); + static const char *dbrefName = "DBRef"; + dbref_class.name = dbrefName; + assert( JS_InitClass( cx , global , 0 , &dbref_class , dbref_constructor , 2 , 0 , bson_functions , 0 , 0 ) ); + scope->exec( jsconcatcode ); } |